@glion/util-semver 0.14.1

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/dist/index.js ADDED
@@ -0,0 +1,504 @@
1
+ //#region src/errors.ts
2
+ /**
3
+ * Error thrown when a version string cannot be parsed.
4
+ */
5
+ var VersionParseError = class VersionParseError extends Error {
6
+ name = "VersionParseError";
7
+ input;
8
+ reason;
9
+ constructor(input, reason) {
10
+ super(`Invalid version format ('${input}') — ${reason}`);
11
+ this.input = input;
12
+ this.reason = reason;
13
+ if (Error.captureStackTrace) Error.captureStackTrace(this, VersionParseError);
14
+ }
15
+ };
16
+ /**
17
+ * Error thrown when a range token cannot be parsed.
18
+ */
19
+ var RangeParseError = class RangeParseError extends Error {
20
+ name = "RangeParseError";
21
+ token;
22
+ reason;
23
+ constructor(token, reason) {
24
+ super(`Invalid range token ('${token}') — ${reason}`);
25
+ this.token = token;
26
+ this.reason = reason;
27
+ if (Error.captureStackTrace) Error.captureStackTrace(this, RangeParseError);
28
+ }
29
+ };
30
+ //#endregion
31
+ //#region src/types.ts
32
+ const MAX_RANGE_STRING_LENGTH = 1e3;
33
+ const MAX_SAFE_VERSION_COMPONENT = 2 ** 31 - 1;
34
+ //#endregion
35
+ //#region src/parse.ts
36
+ const VERSION_RE = /^\s*(\d+)(?:\.(\d+))?(?:\.(\d+))?\s*$/;
37
+ /**
38
+ * Parses a version string into a structured version object.
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const v = parse("2.5.1");
43
+ * // => { major: 2, minor: 5, patch: 1 }
44
+ *
45
+ * parse("2");
46
+ * // => { major: 2, minor: 0, patch: 0 }
47
+ *
48
+ * parse("HELLO");
49
+ * // => throws VersionParseError
50
+ * ```;
51
+ *
52
+ * @param input - Version string to parse (e.g., "2.5.1", "2.3", "2")
53
+ * @returns Structured version with major, minor, and patch components
54
+ * @throws {VersionParseError} If the input format is invalid or exceeds safety
55
+ * limits
56
+ */
57
+ function parse(input) {
58
+ if (input.length > 100) throw new VersionParseError(`${input.slice(0, 50)}...`, `version string too long (max 100 characters)`);
59
+ const match = VERSION_RE.exec(input);
60
+ if (!match) throw new VersionParseError(input, "expected format: major.minor.patch (e.g., '2.5.1' or '2.3')");
61
+ const major = Number(match[1]);
62
+ const minor = match[2] === void 0 ? 0 : Number(match[2]);
63
+ const patch = match[3] === void 0 ? 0 : Number(match[3]);
64
+ if (major > MAX_SAFE_VERSION_COMPONENT) throw new VersionParseError(input, `major version ${major} exceeds maximum ${MAX_SAFE_VERSION_COMPONENT}`);
65
+ if (minor > MAX_SAFE_VERSION_COMPONENT) throw new VersionParseError(input, `minor version ${minor} exceeds maximum ${MAX_SAFE_VERSION_COMPONENT}`);
66
+ if (patch > MAX_SAFE_VERSION_COMPONENT) throw new VersionParseError(input, `patch version ${patch} exceeds maximum ${MAX_SAFE_VERSION_COMPONENT}`);
67
+ return {
68
+ major,
69
+ minor,
70
+ patch
71
+ };
72
+ }
73
+ /**
74
+ * Converts a version string to canonical format (major.minor.patch).
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * clean("2"); // => "2.0.0"
79
+ * clean("2.5"); // => "2.5.0"
80
+ * clean(" 2.5 "); // => "2.5.0"
81
+ * ```;
82
+ *
83
+ * @param input - Version string to clean
84
+ * @returns Canonical version string
85
+ * @throws {VersionParseError} If the input format is invalid
86
+ */
87
+ function clean(input) {
88
+ const v = parse(input);
89
+ return `${v.major}.${v.minor}.${v.patch}`;
90
+ }
91
+ /**
92
+ * Checks if a string is a valid version format.
93
+ * This function never throws - use it for validation.
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * valid("2.5.1"); // => true
98
+ * valid("2"); // => true
99
+ * valid("HELLO"); // => false
100
+ * valid("2."); // => false
101
+ * ```;
102
+ *
103
+ * @param input - Version string to validate
104
+ * @returns True if valid, false otherwise
105
+ */
106
+ function valid(input) {
107
+ try {
108
+ parse(input);
109
+ return true;
110
+ } catch {
111
+ return false;
112
+ }
113
+ }
114
+ /**
115
+ * Internal helper to ensure a value is a parsed Hl7Version object.
116
+ * Parses strings, returns objects as-is.
117
+ *
118
+ * @internal
119
+ */
120
+ function ensure(v) {
121
+ if (typeof v === "string") return parse(v);
122
+ return v;
123
+ }
124
+ /**
125
+ * Increments a version component and resets all lower components to zero.
126
+ *
127
+ * @example
128
+ * ```typescript
129
+ * increment("2.5.1", "major"); // => "3.0.0"
130
+ * increment("2.5.1", "minor"); // => "2.6.0"
131
+ * increment("2.5.1", "patch"); // => "2.5.2"
132
+ *
133
+ * // Works with partial versions too
134
+ * increment("2", "minor"); // => "2.1.0"
135
+ * increment("2.5", "patch"); // => "2.5.1"
136
+ * ```;
137
+ *
138
+ * @param version - Version string to increment
139
+ * @param release - Component to increment: 'major', 'minor', or 'patch'
140
+ * @returns New version string with incremented component
141
+ * @throws {VersionParseError} If version string is invalid
142
+ */
143
+ function increment(version, release) {
144
+ const v = parse(version);
145
+ switch (release) {
146
+ case "major": return `${v.major + 1}.0.0`;
147
+ case "minor": return `${v.major}.${v.minor + 1}.0`;
148
+ case "patch": return `${v.major}.${v.minor}.${v.patch + 1}`;
149
+ }
150
+ }
151
+ //#endregion
152
+ //#region src/compare.ts
153
+ /**
154
+ * Compares two versions and returns their relationship.
155
+ *
156
+ * @example
157
+ * ```typescript
158
+ * compare("2.5.1", "2.5.0"); // => 1
159
+ * compare("2.3", "2.5"); // => -1
160
+ * compare("2.5.1", "2.5.1"); // => 0
161
+ *
162
+ * // Works with parsed versions too
163
+ * const v1 = parse("2.5.1");
164
+ * const v2 = parse("2.5.0");
165
+ * compare(v1, v2); // => 1
166
+ * ```;
167
+ *
168
+ * @param a - First version (string or parsed object)
169
+ * @param b - Second version (string or parsed object)
170
+ * @returns -1 if a < b, 0 if a = b, 1 if a > b
171
+ * @throws {VersionParseError} If either input is an invalid version string
172
+ */
173
+ function compare(a, b) {
174
+ const va = ensure(a);
175
+ const vb = ensure(b);
176
+ for (const key of [
177
+ "major",
178
+ "minor",
179
+ "patch"
180
+ ]) if (va[key] !== vb[key]) return va[key] < vb[key] ? -1 : 1;
181
+ return 0;
182
+ }
183
+ /**
184
+ * Checks if two versions are equal.
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * eq("2.5.1", "2.5.1"); // => true
189
+ * eq("2.5", "2.5.0"); // => true (normalized)
190
+ * eq("2.5.1", "2.5.0"); // => false
191
+ * ```;
192
+ *
193
+ * @param a - First version (string or parsed object)
194
+ * @param b - Second version (string or parsed object)
195
+ * @returns True if versions are equal, false otherwise
196
+ * @throws {VersionParseError} If either input is an invalid version string
197
+ */
198
+ function eq(a, b) {
199
+ return compare(a, b) === 0;
200
+ }
201
+ /**
202
+ * Checks if first version is less than second version.
203
+ *
204
+ * @example
205
+ * ```typescript
206
+ * lt("2.3.0", "2.5.1"); // => true
207
+ * lt("2.5.1", "2.5.1"); // => false
208
+ * lt("2.5.1", "2.3.0"); // => false
209
+ * ```;
210
+ *
211
+ * @param a - First version (string or parsed object)
212
+ * @param b - Second version (string or parsed object)
213
+ * @returns True if a < b, false otherwise
214
+ * @throws {VersionParseError} If either input is an invalid version string
215
+ */
216
+ function lt(a, b) {
217
+ return compare(a, b) === -1;
218
+ }
219
+ /**
220
+ * Checks if first version is less than or equal to second version.
221
+ *
222
+ * @example
223
+ * ```typescript
224
+ * lte("2.3.0", "2.5.1"); // => true
225
+ * lte("2.5.1", "2.5.1"); // => true
226
+ * lte("2.5.1", "2.3.0"); // => false
227
+ * ```;
228
+ *
229
+ * @param a - First version (string or parsed object)
230
+ * @param b - Second version (string or parsed object)
231
+ * @returns True if a <= b, false otherwise
232
+ * @throws {VersionParseError} If either input is an invalid version string
233
+ */
234
+ function lte(a, b) {
235
+ return compare(a, b) !== 1;
236
+ }
237
+ /**
238
+ * Checks if first version is greater than second version.
239
+ *
240
+ * @example
241
+ * ```typescript
242
+ * gt("2.5.1", "2.3.0"); // => true
243
+ * gt("2.5.1", "2.5.1"); // => false
244
+ * gt("2.3.0", "2.5.1"); // => false
245
+ * ```;
246
+ *
247
+ * @param a - First version (string or parsed object)
248
+ * @param b - Second version (string or parsed object)
249
+ * @returns True if a > b, false otherwise
250
+ * @throws {VersionParseError} If either input is an invalid version string
251
+ */
252
+ function gt(a, b) {
253
+ return compare(a, b) === 1;
254
+ }
255
+ /**
256
+ * Checks if first version is greater than or equal to second version.
257
+ *
258
+ * @example
259
+ * ```typescript
260
+ * gte("2.5.1", "2.3.0"); // => true
261
+ * gte("2.5.1", "2.5.1"); // => true
262
+ * gte("2.3.0", "2.5.1"); // => false
263
+ * ```;
264
+ *
265
+ * @param a - First version (string or parsed object)
266
+ * @param b - Second version (string or parsed object)
267
+ * @returns True if a >= b, false otherwise
268
+ * @throws {VersionParseError} If either input is an invalid version string
269
+ */
270
+ function gte(a, b) {
271
+ return compare(a, b) !== -1;
272
+ }
273
+ /**
274
+ * Determines the highest-level component that differs between two versions.
275
+ *
276
+ * @example
277
+ * ```typescript
278
+ * diff("2.5.1", "3.0.0"); // => "major"
279
+ * diff("2.5.1", "2.6.0"); // => "minor"
280
+ * diff("2.5.1", "2.5.2"); // => "patch"
281
+ * diff("2.5.1", "2.5.1"); // => null (equal)
282
+ *
283
+ * // Works with partial versions
284
+ * diff("2", "2.0.0"); // => null (normalized to same)
285
+ * diff("2.5", "2.6"); // => "minor"
286
+ * ```;
287
+ *
288
+ * @param v1 - First version (string or parsed object)
289
+ * @param v2 - Second version (string or parsed object)
290
+ * @returns 'major', 'minor', 'patch', or null if versions are equal
291
+ * @throws {VersionParseError} If either input is an invalid version string
292
+ */
293
+ function diff(v1, v2) {
294
+ const a = ensure(v1);
295
+ const b = ensure(v2);
296
+ if (a.major !== b.major) return "major";
297
+ if (a.minor !== b.minor) return "minor";
298
+ if (a.patch !== b.patch) return "patch";
299
+ return null;
300
+ }
301
+ //#endregion
302
+ //#region src/range.ts
303
+ const RANGE_TOKEN_RE = /^(<=|>=|<|>|=)?\s*(\d+(?:\.\d+){0,2})$/;
304
+ const WS_RE = /\s+/;
305
+ /**
306
+ * Splits a range string into individual tokens.
307
+ *
308
+ * @internal
309
+ */
310
+ function splitTokens(range) {
311
+ const trimmed = range.trim();
312
+ return trimmed.length === 0 ? [] : trimmed.split(WS_RE);
313
+ }
314
+ /**
315
+ * Parses a single range token into a comparator.
316
+ *
317
+ * @internal
318
+ */
319
+ function parseToken(token) {
320
+ const m = RANGE_TOKEN_RE.exec(token);
321
+ if (!m) throw new RangeParseError(token, "expected format: [operator]version (e.g., '>=2.5' or '2.3')");
322
+ return {
323
+ op: m[1] || "=",
324
+ v: parse(m[2] || "")
325
+ };
326
+ }
327
+ /**
328
+ * Maps comparison operators to test functions.
329
+ *
330
+ * @internal
331
+ */
332
+ const OP_TEST = {
333
+ "<": (c) => c < 0,
334
+ "<=": (c) => c <= 0,
335
+ "=": (c) => c === 0,
336
+ ">": (c) => c > 0,
337
+ ">=": (c) => c >= 0
338
+ };
339
+ /**
340
+ * Pre-parsed range expression for efficient reuse.
341
+ *
342
+ * Parse a range once and reuse it for multiple version checks,
343
+ * avoiding repeated parsing overhead.
344
+ *
345
+ * @example
346
+ * ```typescript
347
+ * // Parse once
348
+ * const range = new Range(">=2.0 <3.0");
349
+ *
350
+ * // Reuse many times (much faster than re-parsing)
351
+ * satisfies("2.5.1", range); // => true
352
+ * satisfies("2.3.0", range); // => true
353
+ * satisfies("3.0.0", range); // => false
354
+ * ```;
355
+ */
356
+ var Range = class {
357
+ comparators;
358
+ raw;
359
+ constructor(range) {
360
+ if (range.length > 1e3) throw new RangeParseError(`${range.slice(0, 50)}...`, `range string too long (max ${MAX_RANGE_STRING_LENGTH} characters)`);
361
+ this.raw = range;
362
+ this.comparators = splitTokens(range).map(parseToken);
363
+ }
364
+ /**
365
+ * Test if a version satisfies this range.
366
+ *
367
+ * @param version - Version string to test
368
+ * @returns True if version satisfies all comparators
369
+ * @throws {VersionParseError} If version string is invalid
370
+ */
371
+ test(version) {
372
+ if (this.comparators.length === 0) return false;
373
+ const v = parse(version);
374
+ for (const c of this.comparators) {
375
+ const cmp = compare(v, c.v);
376
+ if (!OP_TEST[c.op](cmp)) return false;
377
+ }
378
+ return true;
379
+ }
380
+ };
381
+ /**
382
+ * Checks if a version satisfies a range expression.
383
+ *
384
+ * Range expressions consist of one or more space-separated comparators.
385
+ * Each comparator is an optional operator followed by a version.
386
+ *
387
+ * Supported operators:
388
+ *
389
+ * - `=` (or no operator): exact match
390
+ * - `<`: less than
391
+ * - `<=`: less than or equal
392
+ * - `>`: greater than
393
+ * - `>=`: greater than or equal
394
+ *
395
+ * Multiple comparators create AND conditions - all must be satisfied.
396
+ *
397
+ * For performance when checking many versions against the same range,
398
+ * use a Range object instead of a string.
399
+ *
400
+ * @example
401
+ * ```typescript
402
+ * // String range (parsed every call)
403
+ * satisfies("2.5.1", ">=2.0 <3.0"); // => true
404
+ * satisfies("2.5.1", "2.5.1"); // => true (exact match)
405
+ * satisfies("2.5.1", ">=2.6"); // => false
406
+ *
407
+ * // Range object (parse once, reuse many times - much faster)
408
+ * const range = new Range(">=2.0 <3.0");
409
+ * satisfies("2.5.1", range); // => true
410
+ * satisfies("2.3.0", range); // => true
411
+ * satisfies("3.0.0", range); // => false
412
+ * ```;
413
+ *
414
+ * @param version - Version string to test
415
+ * @param range - Range expression string or pre-parsed Range object
416
+ * @returns True if version satisfies all comparators, false for empty range
417
+ * @throws {VersionParseError} If version string is invalid
418
+ * @throws {RangeParseError} If range expression is invalid or exceeds length
419
+ * limit
420
+ */
421
+ function satisfies(version, range) {
422
+ return (range instanceof Range ? range : new Range(range)).test(version);
423
+ }
424
+ //#endregion
425
+ //#region src/collection.ts
426
+ /**
427
+ * Sorts an array of version strings in ascending order.
428
+ *
429
+ * @example
430
+ * ```typescript
431
+ * sort(["2.5", "2.3.1", "2.10.0"]);
432
+ * // => ["2.3.1", "2.5", "2.10.0"]
433
+ *
434
+ * sort(["2.10", "2.9", "2.8"]);
435
+ * // => ["2.8", "2.9", "2.10"]
436
+ * ```;
437
+ *
438
+ * @param versions - Array of version strings to sort
439
+ * @returns New sorted array (does not mutate input)
440
+ * @throws {VersionParseError} If any version string is invalid
441
+ */
442
+ function sort(versions) {
443
+ return [...versions].toSorted((a, b) => compare(a, b));
444
+ }
445
+ /**
446
+ * Finds the highest version that satisfies a range.
447
+ *
448
+ * @example
449
+ * ```typescript
450
+ * maxSatisfying(["2.3.0", "2.5.1", "3.0.0"], ">=2.0 <3.0");
451
+ * // => "2.5.1"
452
+ *
453
+ * maxSatisfying(["2.3.0", "2.5.1"], ">=3.0");
454
+ * // => null (no matches)
455
+ *
456
+ * // Use Range object for better performance with many versions
457
+ * const range = new Range(">=2.0 <3.0");
458
+ * maxSatisfying(["2.3.0", "2.5.1", "3.0.0"], range);
459
+ * // => "2.5.1"
460
+ * ```;
461
+ *
462
+ * @param versions - Array of version strings to search
463
+ * @param range - Range expression string or pre-parsed Range object
464
+ * @returns Highest matching version, or null if none match
465
+ * @throws {VersionParseError} If any version string is invalid
466
+ * @throws {RangeParseError} If range expression is invalid
467
+ */
468
+ function maxSatisfying(versions, range) {
469
+ let max = null;
470
+ for (const version of versions) if (satisfies(version, range) && (max === null || compare(version, max) === 1)) max = version;
471
+ return max;
472
+ }
473
+ /**
474
+ * Finds the lowest version that satisfies a range.
475
+ *
476
+ * @example
477
+ * ```typescript
478
+ * minSatisfying(["2.3.0", "2.5.1", "3.0.0"], ">=2.0 <3.0");
479
+ * // => "2.3.0"
480
+ *
481
+ * minSatisfying(["2.3.0", "2.5.1"], ">=3.0");
482
+ * // => null (no matches)
483
+ *
484
+ * // Use Range object for better performance with many versions
485
+ * const range = new Range(">=2.0 <3.0");
486
+ * minSatisfying(["2.3.0", "2.5.1", "3.0.0"], range);
487
+ * // => "2.3.0"
488
+ * ```;
489
+ *
490
+ * @param versions - Array of version strings to search
491
+ * @param range - Range expression string or pre-parsed Range object
492
+ * @returns Lowest matching version, or null if none match
493
+ * @throws {VersionParseError} If any version string is invalid
494
+ * @throws {RangeParseError} If range expression is invalid
495
+ */
496
+ function minSatisfying(versions, range) {
497
+ let min = null;
498
+ for (const version of versions) if (satisfies(version, range) && (min === null || compare(version, min) === -1)) min = version;
499
+ return min;
500
+ }
501
+ //#endregion
502
+ export { Range, RangeParseError, VersionParseError, clean, compare, diff, eq, gt, gte, increment, lt, lte, maxSatisfying, minSatisfying, parse, satisfies, sort, valid };
503
+
504
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/errors.ts","../src/types.ts","../src/parse.ts","../src/compare.ts","../src/range.ts","../src/collection.ts"],"sourcesContent":["/**\n * Error thrown when a version string cannot be parsed.\n */\nexport class VersionParseError extends Error {\n override readonly name = \"VersionParseError\";\n readonly input: string;\n readonly reason: string;\n\n constructor(input: string, reason: string) {\n super(`Invalid version format ('${input}') — ${reason}`);\n\n this.input = input;\n this.reason = reason;\n\n // Maintains proper stack trace for where error was thrown (V8 only)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, VersionParseError);\n }\n }\n}\n\n/**\n * Error thrown when a range token cannot be parsed.\n */\nexport class RangeParseError extends Error {\n override readonly name = \"RangeParseError\";\n readonly token: string;\n readonly reason: string;\n\n constructor(token: string, reason: string) {\n super(`Invalid range token ('${token}') — ${reason}`);\n\n this.token = token;\n this.reason = reason;\n\n // Maintains proper stack trace for where error was thrown (V8 only)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, RangeParseError);\n }\n }\n}\n","/**\n * Represents a semantic version with major, minor, and patch components.\n */\nexport interface Hl7Version {\n major: number;\n minor: number;\n patch: number;\n}\n\n/**\n * Comparison operators supported in version ranges.\n */\nexport type ComparisonOperator = \"=\" | \"<\" | \"<=\" | \">\" | \">=\";\n\n/**\n * Internal representation of a version range comparator.\n */\nexport interface Comparator {\n op: ComparisonOperator;\n v: Hl7Version;\n}\n\n/**\n * Result of a comparison operation.\n */\nexport type ComparisonResult = -1 | 0 | 1;\n\n/**\n * Security constraints for input validation.\n */\nexport const MAX_VERSION_STRING_LENGTH = 100;\nexport const MAX_RANGE_STRING_LENGTH = 1000;\nexport const MAX_SAFE_VERSION_COMPONENT = 2 ** 31 - 1; // Max safe int32 for interop\n","import { VersionParseError } from \"./errors\";\nimport type { Hl7Version } from \"./types\";\nimport { MAX_SAFE_VERSION_COMPONENT, MAX_VERSION_STRING_LENGTH } from \"./types\";\n\n// Regex for parsing version strings\nconst VERSION_RE = /^\\s*(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?\\s*$/;\n\n/**\n * Parses a version string into a structured version object.\n *\n * @example\n * ```typescript\n * const v = parse(\"2.5.1\");\n * // => { major: 2, minor: 5, patch: 1 }\n *\n * parse(\"2\");\n * // => { major: 2, minor: 0, patch: 0 }\n *\n * parse(\"HELLO\");\n * // => throws VersionParseError\n * ```;\n *\n * @param input - Version string to parse (e.g., \"2.5.1\", \"2.3\", \"2\")\n * @returns Structured version with major, minor, and patch components\n * @throws {VersionParseError} If the input format is invalid or exceeds safety\n * limits\n */\nexport function parse(input: string): Hl7Version {\n // Length check to prevent ReDoS attacks\n if (input.length > MAX_VERSION_STRING_LENGTH) {\n throw new VersionParseError(\n `${input.slice(0, 50)}...`,\n `version string too long (max ${MAX_VERSION_STRING_LENGTH} characters)`\n );\n }\n\n const match = VERSION_RE.exec(input);\n if (!match) {\n throw new VersionParseError(\n input,\n \"expected format: major.minor.patch (e.g., '2.5.1' or '2.3')\"\n );\n }\n\n // Regex ensures digits-only, Number() on digits always yields valid integers\n const major = Number(match[1]);\n const minor = match[2] === undefined ? 0 : Number(match[2]);\n const patch = match[3] === undefined ? 0 : Number(match[3]);\n\n // Validate range to prevent integer overflow and ensure interoperability\n if (major > MAX_SAFE_VERSION_COMPONENT) {\n throw new VersionParseError(\n input,\n `major version ${major} exceeds maximum ${MAX_SAFE_VERSION_COMPONENT}`\n );\n }\n if (minor > MAX_SAFE_VERSION_COMPONENT) {\n throw new VersionParseError(\n input,\n `minor version ${minor} exceeds maximum ${MAX_SAFE_VERSION_COMPONENT}`\n );\n }\n if (patch > MAX_SAFE_VERSION_COMPONENT) {\n throw new VersionParseError(\n input,\n `patch version ${patch} exceeds maximum ${MAX_SAFE_VERSION_COMPONENT}`\n );\n }\n\n return { major, minor, patch };\n}\n\n/**\n * Converts a version string to canonical format (major.minor.patch).\n *\n * @example\n * ```typescript\n * clean(\"2\"); // => \"2.0.0\"\n * clean(\"2.5\"); // => \"2.5.0\"\n * clean(\" 2.5 \"); // => \"2.5.0\"\n * ```;\n *\n * @param input - Version string to clean\n * @returns Canonical version string\n * @throws {VersionParseError} If the input format is invalid\n */\nexport function clean(input: string): string {\n const v = parse(input);\n return `${v.major}.${v.minor}.${v.patch}`;\n}\n\n/**\n * Checks if a string is a valid version format.\n * This function never throws - use it for validation.\n *\n * @example\n * ```typescript\n * valid(\"2.5.1\"); // => true\n * valid(\"2\"); // => true\n * valid(\"HELLO\"); // => false\n * valid(\"2.\"); // => false\n * ```;\n *\n * @param input - Version string to validate\n * @returns True if valid, false otherwise\n */\nexport function valid(input: string): boolean {\n try {\n parse(input);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Internal helper to ensure a value is a parsed Hl7Version object.\n * Parses strings, returns objects as-is.\n *\n * @internal\n */\nexport function ensure(v: string | Hl7Version): Hl7Version {\n if (typeof v === \"string\") {\n return parse(v);\n }\n return v;\n}\n\n/**\n * Increments a version component and resets all lower components to zero.\n *\n * @example\n * ```typescript\n * increment(\"2.5.1\", \"major\"); // => \"3.0.0\"\n * increment(\"2.5.1\", \"minor\"); // => \"2.6.0\"\n * increment(\"2.5.1\", \"patch\"); // => \"2.5.2\"\n *\n * // Works with partial versions too\n * increment(\"2\", \"minor\"); // => \"2.1.0\"\n * increment(\"2.5\", \"patch\"); // => \"2.5.1\"\n * ```;\n *\n * @param version - Version string to increment\n * @param release - Component to increment: 'major', 'minor', or 'patch'\n * @returns New version string with incremented component\n * @throws {VersionParseError} If version string is invalid\n */\nexport function increment(\n version: string,\n release: \"major\" | \"minor\" | \"patch\"\n): string {\n const v = parse(version);\n\n // biome-ignore lint/style/useDefaultSwitchClause: default case in the switch statement is unreachable\n switch (release) {\n case \"major\": {\n return `${v.major + 1}.0.0`;\n }\n case \"minor\": {\n return `${v.major}.${v.minor + 1}.0`;\n }\n case \"patch\": {\n return `${v.major}.${v.minor}.${v.patch + 1}`;\n }\n }\n}\n","import { ensure } from \"./parse\";\nimport type { ComparisonResult, Hl7Version } from \"./types\";\n\n/**\n * Compares two versions and returns their relationship.\n *\n * @example\n * ```typescript\n * compare(\"2.5.1\", \"2.5.0\"); // => 1\n * compare(\"2.3\", \"2.5\"); // => -1\n * compare(\"2.5.1\", \"2.5.1\"); // => 0\n *\n * // Works with parsed versions too\n * const v1 = parse(\"2.5.1\");\n * const v2 = parse(\"2.5.0\");\n * compare(v1, v2); // => 1\n * ```;\n *\n * @param a - First version (string or parsed object)\n * @param b - Second version (string or parsed object)\n * @returns -1 if a < b, 0 if a = b, 1 if a > b\n * @throws {VersionParseError} If either input is an invalid version string\n */\nexport function compare(\n a: string | Hl7Version,\n b: string | Hl7Version\n): ComparisonResult {\n const va = ensure(a);\n const vb = ensure(b);\n\n // Compare in order: major, minor, patch\n for (const key of [\"major\", \"minor\", \"patch\"] as const) {\n if (va[key] !== vb[key]) {\n return va[key] < vb[key] ? -1 : 1;\n }\n }\n return 0;\n}\n\n/**\n * Checks if two versions are equal.\n *\n * @example\n * ```typescript\n * eq(\"2.5.1\", \"2.5.1\"); // => true\n * eq(\"2.5\", \"2.5.0\"); // => true (normalized)\n * eq(\"2.5.1\", \"2.5.0\"); // => false\n * ```;\n *\n * @param a - First version (string or parsed object)\n * @param b - Second version (string or parsed object)\n * @returns True if versions are equal, false otherwise\n * @throws {VersionParseError} If either input is an invalid version string\n */\nexport function eq(a: string | Hl7Version, b: string | Hl7Version): boolean {\n return compare(a, b) === 0;\n}\n\n/**\n * Checks if first version is less than second version.\n *\n * @example\n * ```typescript\n * lt(\"2.3.0\", \"2.5.1\"); // => true\n * lt(\"2.5.1\", \"2.5.1\"); // => false\n * lt(\"2.5.1\", \"2.3.0\"); // => false\n * ```;\n *\n * @param a - First version (string or parsed object)\n * @param b - Second version (string or parsed object)\n * @returns True if a < b, false otherwise\n * @throws {VersionParseError} If either input is an invalid version string\n */\nexport function lt(a: string | Hl7Version, b: string | Hl7Version): boolean {\n return compare(a, b) === -1;\n}\n\n/**\n * Checks if first version is less than or equal to second version.\n *\n * @example\n * ```typescript\n * lte(\"2.3.0\", \"2.5.1\"); // => true\n * lte(\"2.5.1\", \"2.5.1\"); // => true\n * lte(\"2.5.1\", \"2.3.0\"); // => false\n * ```;\n *\n * @param a - First version (string or parsed object)\n * @param b - Second version (string or parsed object)\n * @returns True if a <= b, false otherwise\n * @throws {VersionParseError} If either input is an invalid version string\n */\nexport function lte(a: string | Hl7Version, b: string | Hl7Version): boolean {\n return compare(a, b) !== 1;\n}\n\n/**\n * Checks if first version is greater than second version.\n *\n * @example\n * ```typescript\n * gt(\"2.5.1\", \"2.3.0\"); // => true\n * gt(\"2.5.1\", \"2.5.1\"); // => false\n * gt(\"2.3.0\", \"2.5.1\"); // => false\n * ```;\n *\n * @param a - First version (string or parsed object)\n * @param b - Second version (string or parsed object)\n * @returns True if a > b, false otherwise\n * @throws {VersionParseError} If either input is an invalid version string\n */\nexport function gt(a: string | Hl7Version, b: string | Hl7Version): boolean {\n return compare(a, b) === 1;\n}\n\n/**\n * Checks if first version is greater than or equal to second version.\n *\n * @example\n * ```typescript\n * gte(\"2.5.1\", \"2.3.0\"); // => true\n * gte(\"2.5.1\", \"2.5.1\"); // => true\n * gte(\"2.3.0\", \"2.5.1\"); // => false\n * ```;\n *\n * @param a - First version (string or parsed object)\n * @param b - Second version (string or parsed object)\n * @returns True if a >= b, false otherwise\n * @throws {VersionParseError} If either input is an invalid version string\n */\nexport function gte(a: string | Hl7Version, b: string | Hl7Version): boolean {\n return compare(a, b) !== -1;\n}\n\n/**\n * Determines the highest-level component that differs between two versions.\n *\n * @example\n * ```typescript\n * diff(\"2.5.1\", \"3.0.0\"); // => \"major\"\n * diff(\"2.5.1\", \"2.6.0\"); // => \"minor\"\n * diff(\"2.5.1\", \"2.5.2\"); // => \"patch\"\n * diff(\"2.5.1\", \"2.5.1\"); // => null (equal)\n *\n * // Works with partial versions\n * diff(\"2\", \"2.0.0\"); // => null (normalized to same)\n * diff(\"2.5\", \"2.6\"); // => \"minor\"\n * ```;\n *\n * @param v1 - First version (string or parsed object)\n * @param v2 - Second version (string or parsed object)\n * @returns 'major', 'minor', 'patch', or null if versions are equal\n * @throws {VersionParseError} If either input is an invalid version string\n */\nexport function diff(\n v1: string | Hl7Version,\n v2: string | Hl7Version\n): \"major\" | \"minor\" | \"patch\" | null {\n const a = ensure(v1);\n const b = ensure(v2);\n\n if (a.major !== b.major) {\n return \"major\";\n }\n if (a.minor !== b.minor) {\n return \"minor\";\n }\n if (a.patch !== b.patch) {\n return \"patch\";\n }\n return null;\n}\n","import { compare } from \"./compare\";\nimport { RangeParseError } from \"./errors\";\nimport { parse } from \"./parse\";\nimport type { Comparator } from \"./types\";\nimport { MAX_RANGE_STRING_LENGTH } from \"./types\";\n\n// Regex for parsing range tokens\nconst RANGE_TOKEN_RE = /^(<=|>=|<|>|=)?\\s*(\\d+(?:\\.\\d+){0,2})$/;\n\n// Whitespace splitter for range expressions\nconst WS_RE = /\\s+/;\n\n/**\n * Splits a range string into individual tokens.\n *\n * @internal\n */\nfunction splitTokens(range: string): string[] {\n const trimmed = range.trim();\n return trimmed.length === 0 ? [] : trimmed.split(WS_RE);\n}\n\n/**\n * Parses a single range token into a comparator.\n *\n * @internal\n */\nfunction parseToken(token: string): Comparator {\n const m = RANGE_TOKEN_RE.exec(token);\n if (!m) {\n throw new RangeParseError(\n token,\n \"expected format: [operator]version (e.g., '>=2.5' or '2.3')\"\n );\n }\n\n // m[1] is optional operator, m[2] is required version (guaranteed by regex)\n const op = (m[1] || \"=\") as Comparator[\"op\"];\n // biome-ignore lint/style/noNonNullAssertion: Non-null assertion safe: regex guarantees m[2] exists\n const v = parse(m[2] || \"\");\n return { op, v };\n}\n\n/**\n * Maps comparison operators to test functions.\n *\n * @internal\n */\nconst OP_TEST: Record<Comparator[\"op\"], (cmp: number) => boolean> = {\n \"<\": (c) => c < 0,\n \"<=\": (c) => c <= 0,\n \"=\": (c) => c === 0,\n \">\": (c) => c > 0,\n \">=\": (c) => c >= 0,\n};\n\n/**\n * Pre-parsed range expression for efficient reuse.\n *\n * Parse a range once and reuse it for multiple version checks,\n * avoiding repeated parsing overhead.\n *\n * @example\n * ```typescript\n * // Parse once\n * const range = new Range(\">=2.0 <3.0\");\n *\n * // Reuse many times (much faster than re-parsing)\n * satisfies(\"2.5.1\", range); // => true\n * satisfies(\"2.3.0\", range); // => true\n * satisfies(\"3.0.0\", range); // => false\n * ```;\n */\nexport class Range {\n readonly comparators: readonly Comparator[];\n readonly raw: string;\n\n constructor(range: string) {\n // Length check for range string to prevent ReDoS attacks\n if (range.length > MAX_RANGE_STRING_LENGTH) {\n throw new RangeParseError(\n `${range.slice(0, 50)}...`,\n `range string too long (max ${MAX_RANGE_STRING_LENGTH} characters)`\n );\n }\n\n this.raw = range;\n const tokens = splitTokens(range);\n this.comparators = tokens.map(parseToken);\n }\n\n /**\n * Test if a version satisfies this range.\n *\n * @param version - Version string to test\n * @returns True if version satisfies all comparators\n * @throws {VersionParseError} If version string is invalid\n */\n test(version: string): boolean {\n if (this.comparators.length === 0) {\n return false;\n }\n\n const v = parse(version);\n for (const c of this.comparators) {\n const cmp = compare(v, c.v);\n if (!OP_TEST[c.op](cmp)) {\n return false;\n }\n }\n return true;\n }\n}\n\n/**\n * Checks if a version satisfies a range expression.\n *\n * Range expressions consist of one or more space-separated comparators.\n * Each comparator is an optional operator followed by a version.\n *\n * Supported operators:\n *\n * - `=` (or no operator): exact match\n * - `<`: less than\n * - `<=`: less than or equal\n * - `>`: greater than\n * - `>=`: greater than or equal\n *\n * Multiple comparators create AND conditions - all must be satisfied.\n *\n * For performance when checking many versions against the same range,\n * use a Range object instead of a string.\n *\n * @example\n * ```typescript\n * // String range (parsed every call)\n * satisfies(\"2.5.1\", \">=2.0 <3.0\"); // => true\n * satisfies(\"2.5.1\", \"2.5.1\"); // => true (exact match)\n * satisfies(\"2.5.1\", \">=2.6\"); // => false\n *\n * // Range object (parse once, reuse many times - much faster)\n * const range = new Range(\">=2.0 <3.0\");\n * satisfies(\"2.5.1\", range); // => true\n * satisfies(\"2.3.0\", range); // => true\n * satisfies(\"3.0.0\", range); // => false\n * ```;\n *\n * @param version - Version string to test\n * @param range - Range expression string or pre-parsed Range object\n * @returns True if version satisfies all comparators, false for empty range\n * @throws {VersionParseError} If version string is invalid\n * @throws {RangeParseError} If range expression is invalid or exceeds length\n * limit\n */\nexport function satisfies(version: string, range: string | Range): boolean {\n const rangeObj = range instanceof Range ? range : new Range(range);\n return rangeObj.test(version);\n}\n","import { compare } from \"./compare\";\nimport { satisfies } from \"./range\";\nimport type { Range } from \"./range\";\n\n/**\n * Sorts an array of version strings in ascending order.\n *\n * @example\n * ```typescript\n * sort([\"2.5\", \"2.3.1\", \"2.10.0\"]);\n * // => [\"2.3.1\", \"2.5\", \"2.10.0\"]\n *\n * sort([\"2.10\", \"2.9\", \"2.8\"]);\n * // => [\"2.8\", \"2.9\", \"2.10\"]\n * ```;\n *\n * @param versions - Array of version strings to sort\n * @returns New sorted array (does not mutate input)\n * @throws {VersionParseError} If any version string is invalid\n */\nexport function sort(versions: string[]): string[] {\n return [...versions].toSorted((a, b) => compare(a, b));\n}\n\n/**\n * Finds the highest version that satisfies a range.\n *\n * @example\n * ```typescript\n * maxSatisfying([\"2.3.0\", \"2.5.1\", \"3.0.0\"], \">=2.0 <3.0\");\n * // => \"2.5.1\"\n *\n * maxSatisfying([\"2.3.0\", \"2.5.1\"], \">=3.0\");\n * // => null (no matches)\n *\n * // Use Range object for better performance with many versions\n * const range = new Range(\">=2.0 <3.0\");\n * maxSatisfying([\"2.3.0\", \"2.5.1\", \"3.0.0\"], range);\n * // => \"2.5.1\"\n * ```;\n *\n * @param versions - Array of version strings to search\n * @param range - Range expression string or pre-parsed Range object\n * @returns Highest matching version, or null if none match\n * @throws {VersionParseError} If any version string is invalid\n * @throws {RangeParseError} If range expression is invalid\n */\nexport function maxSatisfying(\n versions: string[],\n range: string | Range\n): string | null {\n let max: string | null = null;\n\n for (const version of versions) {\n if (\n satisfies(version, range) &&\n (max === null || compare(version, max) === 1)\n ) {\n max = version;\n }\n }\n\n return max;\n}\n\n/**\n * Finds the lowest version that satisfies a range.\n *\n * @example\n * ```typescript\n * minSatisfying([\"2.3.0\", \"2.5.1\", \"3.0.0\"], \">=2.0 <3.0\");\n * // => \"2.3.0\"\n *\n * minSatisfying([\"2.3.0\", \"2.5.1\"], \">=3.0\");\n * // => null (no matches)\n *\n * // Use Range object for better performance with many versions\n * const range = new Range(\">=2.0 <3.0\");\n * minSatisfying([\"2.3.0\", \"2.5.1\", \"3.0.0\"], range);\n * // => \"2.3.0\"\n * ```;\n *\n * @param versions - Array of version strings to search\n * @param range - Range expression string or pre-parsed Range object\n * @returns Lowest matching version, or null if none match\n * @throws {VersionParseError} If any version string is invalid\n * @throws {RangeParseError} If range expression is invalid\n */\nexport function minSatisfying(\n versions: string[],\n range: string | Range\n): string | null {\n let min: string | null = null;\n\n for (const version of versions) {\n if (\n satisfies(version, range) &&\n (min === null || compare(version, min) === -1)\n ) {\n min = version;\n }\n }\n\n return min;\n}\n"],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import type { Hl7Version } from "./types";
2
+ /**
3
+ * Parses a version string into a structured version object.
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * const v = parse("2.5.1");
8
+ * // => { major: 2, minor: 5, patch: 1 }
9
+ *
10
+ * parse("2");
11
+ * // => { major: 2, minor: 0, patch: 0 }
12
+ *
13
+ * parse("HELLO");
14
+ * // => throws VersionParseError
15
+ * ```;
16
+ *
17
+ * @param input - Version string to parse (e.g., "2.5.1", "2.3", "2")
18
+ * @returns Structured version with major, minor, and patch components
19
+ * @throws {VersionParseError} If the input format is invalid or exceeds safety
20
+ * limits
21
+ */
22
+ export declare function parse(input: string): Hl7Version;
23
+ /**
24
+ * Converts a version string to canonical format (major.minor.patch).
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * clean("2"); // => "2.0.0"
29
+ * clean("2.5"); // => "2.5.0"
30
+ * clean(" 2.5 "); // => "2.5.0"
31
+ * ```;
32
+ *
33
+ * @param input - Version string to clean
34
+ * @returns Canonical version string
35
+ * @throws {VersionParseError} If the input format is invalid
36
+ */
37
+ export declare function clean(input: string): string;
38
+ /**
39
+ * Checks if a string is a valid version format.
40
+ * This function never throws - use it for validation.
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * valid("2.5.1"); // => true
45
+ * valid("2"); // => true
46
+ * valid("HELLO"); // => false
47
+ * valid("2."); // => false
48
+ * ```;
49
+ *
50
+ * @param input - Version string to validate
51
+ * @returns True if valid, false otherwise
52
+ */
53
+ export declare function valid(input: string): boolean;
54
+ /**
55
+ * Internal helper to ensure a value is a parsed Hl7Version object.
56
+ * Parses strings, returns objects as-is.
57
+ *
58
+ * @internal
59
+ */
60
+ export declare function ensure(v: string | Hl7Version): Hl7Version;
61
+ /**
62
+ * Increments a version component and resets all lower components to zero.
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * increment("2.5.1", "major"); // => "3.0.0"
67
+ * increment("2.5.1", "minor"); // => "2.6.0"
68
+ * increment("2.5.1", "patch"); // => "2.5.2"
69
+ *
70
+ * // Works with partial versions too
71
+ * increment("2", "minor"); // => "2.1.0"
72
+ * increment("2.5", "patch"); // => "2.5.1"
73
+ * ```;
74
+ *
75
+ * @param version - Version string to increment
76
+ * @param release - Component to increment: 'major', 'minor', or 'patch'
77
+ * @returns New version string with incremented component
78
+ * @throws {VersionParseError} If version string is invalid
79
+ */
80
+ export declare function increment(version: string, release: "major" | "minor" | "patch"): string;
81
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAM1C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CA2C/C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAG3C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAO5C;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,CAKzD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GACnC,MAAM,CAeR"}