@naturalcycles/js-lib 14.163.0 → 14.165.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/dist/datetime/localDate.js +4 -6
- package/dist/datetime/localTime.js +10 -11
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/is.util.d.ts +4 -0
- package/dist/is.util.js +8 -1
- package/dist/semver.d.ts +44 -0
- package/dist/semver.js +83 -0
- package/dist-esm/datetime/localDate.js +4 -6
- package/dist-esm/datetime/localTime.js +10 -11
- package/dist-esm/index.js +1 -0
- package/dist-esm/is.util.js +6 -0
- package/dist-esm/semver.js +78 -0
- package/package.json +1 -1
- package/src/datetime/localDate.ts +4 -6
- package/src/datetime/localTime.ts +10 -10
- package/src/index.ts +1 -0
- package/src/is.util.ts +7 -0
- package/src/semver.ts +87 -0
|
@@ -23,16 +23,14 @@ class LocalDate {
|
|
|
23
23
|
*/
|
|
24
24
|
static of(d) {
|
|
25
25
|
const t = this.parseOrNull(d);
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
26
|
+
(0, assert_1._assert)(t !== null, `Cannot parse "${d}" into LocalDate`, {
|
|
27
|
+
input: d,
|
|
28
|
+
});
|
|
29
29
|
return t;
|
|
30
30
|
}
|
|
31
31
|
static parseCompact(d) {
|
|
32
32
|
const [year, month, day] = [d.slice(0, 4), d.slice(4, 2), d.slice(6, 2)].map(Number);
|
|
33
|
-
|
|
34
|
-
throw new Error(`Cannot parse "${d}" into LocalDate`);
|
|
35
|
-
}
|
|
33
|
+
(0, assert_1._assert)(day && month && year, `Cannot parse "${d}" into LocalDate`);
|
|
36
34
|
return new LocalDate(year, month, day);
|
|
37
35
|
}
|
|
38
36
|
static fromDate(d) {
|
|
@@ -33,9 +33,9 @@ class LocalTime {
|
|
|
33
33
|
*/
|
|
34
34
|
static of(d) {
|
|
35
35
|
const t = this.parseOrNull(d);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
36
|
+
(0, assert_1._assert)(t !== null, `Cannot parse "${d}" into LocalTime`, {
|
|
37
|
+
input: d,
|
|
38
|
+
});
|
|
39
39
|
return t;
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
@@ -82,9 +82,9 @@ class LocalTime {
|
|
|
82
82
|
if (d instanceof Date)
|
|
83
83
|
return d;
|
|
84
84
|
const date = typeof d === 'number' ? new Date(d * 1000) : new Date(d);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
85
|
+
(0, assert_1._assert)(!isNaN(date.getDate()), `Cannot parse "${d}" to Date`, {
|
|
86
|
+
input: d,
|
|
87
|
+
});
|
|
88
88
|
return date;
|
|
89
89
|
}
|
|
90
90
|
static parseToUnixTimestamp(d) {
|
|
@@ -93,9 +93,9 @@ class LocalTime {
|
|
|
93
93
|
if (d instanceof LocalTime)
|
|
94
94
|
return d.unix();
|
|
95
95
|
const date = d instanceof Date ? d : new Date(d);
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
96
|
+
(0, assert_1._assert)(!isNaN(date.getDate()), `Cannot parse "${d}" to UnixTimestamp`, {
|
|
97
|
+
input: d,
|
|
98
|
+
});
|
|
99
99
|
return date.valueOf() / 1000;
|
|
100
100
|
}
|
|
101
101
|
static isValid(d) {
|
|
@@ -171,8 +171,7 @@ class LocalTime {
|
|
|
171
171
|
if (v === undefined) {
|
|
172
172
|
return dow;
|
|
173
173
|
}
|
|
174
|
-
|
|
175
|
-
throw new Error(`Invalid dayOfWeek: ${v}`);
|
|
174
|
+
(0, assert_1._assert)(VALID_DAYS_OF_WEEK.has(v), `Invalid dayOfWeek: ${v}`);
|
|
176
175
|
return this.add(v - dow, 'day');
|
|
177
176
|
}
|
|
178
177
|
hour(v) {
|
package/dist/index.d.ts
CHANGED
|
@@ -81,6 +81,7 @@ export * from './http/fetcher.model';
|
|
|
81
81
|
export * from './string/hash.util';
|
|
82
82
|
export * from './env/buildInfo';
|
|
83
83
|
export * from './form.util';
|
|
84
|
+
export * from './semver';
|
|
84
85
|
export * from './zod/zod.util';
|
|
85
86
|
export * from './zod/zod.shared.schemas';
|
|
86
87
|
import { z, ZodSchema, ZodError, ZodIssue } from 'zod';
|
package/dist/index.js
CHANGED
|
@@ -85,6 +85,7 @@ tslib_1.__exportStar(require("./http/fetcher.model"), exports);
|
|
|
85
85
|
tslib_1.__exportStar(require("./string/hash.util"), exports);
|
|
86
86
|
tslib_1.__exportStar(require("./env/buildInfo"), exports);
|
|
87
87
|
tslib_1.__exportStar(require("./form.util"), exports);
|
|
88
|
+
tslib_1.__exportStar(require("./semver"), exports);
|
|
88
89
|
tslib_1.__exportStar(require("./zod/zod.util"), exports);
|
|
89
90
|
tslib_1.__exportStar(require("./zod/zod.shared.schemas"), exports);
|
|
90
91
|
const zod_1 = require("zod");
|
package/dist/is.util.d.ts
CHANGED
package/dist/is.util.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports._isEmpty = exports._isEmptyObject = exports._isPrimitive = exports._isObject = exports._isFalsy = exports._isTruthy = exports._isNotNullish = exports._isNullish = exports._isUndefined = exports._isNull = void 0;
|
|
3
|
+
exports._isNotEmpty = exports._isEmpty = exports._isEmptyObject = exports._isPrimitive = exports._isObject = exports._isFalsy = exports._isTruthy = exports._isNotNullish = exports._isNullish = exports._isUndefined = exports._isNull = void 0;
|
|
4
4
|
const _isNull = (v) => v === null;
|
|
5
5
|
exports._isNull = _isNull;
|
|
6
6
|
const _isUndefined = (v) => v === undefined;
|
|
@@ -70,3 +70,10 @@ function _isEmpty(obj) {
|
|
|
70
70
|
return false;
|
|
71
71
|
}
|
|
72
72
|
exports._isEmpty = _isEmpty;
|
|
73
|
+
/**
|
|
74
|
+
* @see _isEmpty
|
|
75
|
+
*/
|
|
76
|
+
function _isNotEmpty(obj) {
|
|
77
|
+
return !_isEmpty(obj);
|
|
78
|
+
}
|
|
79
|
+
exports._isNotEmpty = _isNotEmpty;
|
package/dist/semver.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export type SemverInput = string | Semver;
|
|
2
|
+
export type SemverTokens = [major: number, minor: number, patch: number];
|
|
3
|
+
/**
|
|
4
|
+
* Simple Semver implementation.
|
|
5
|
+
*
|
|
6
|
+
* Suitable for Browser usage, unlike npm `semver` which is Node-targeted and simply too big for the Browser.
|
|
7
|
+
*
|
|
8
|
+
* Parsing algorithm is simple:
|
|
9
|
+
* 1. Split by `.`
|
|
10
|
+
* 2. parseInt each of 3 tokens, set to 0 if falsy
|
|
11
|
+
*
|
|
12
|
+
* toString returns `major.minor.patch`
|
|
13
|
+
* Missing tokens are replaced with 0.
|
|
14
|
+
*
|
|
15
|
+
* _semver('1').toString() === '1.0.0'
|
|
16
|
+
*
|
|
17
|
+
* @experimental
|
|
18
|
+
*/
|
|
19
|
+
export declare class Semver {
|
|
20
|
+
tokens: SemverTokens;
|
|
21
|
+
private constructor();
|
|
22
|
+
get major(): number;
|
|
23
|
+
get minor(): number;
|
|
24
|
+
get patch(): number;
|
|
25
|
+
static of(input: SemverInput): Semver;
|
|
26
|
+
static parseOrNull(input: SemverInput | undefined | null): Semver | null;
|
|
27
|
+
isAfter: (other: SemverInput) => boolean;
|
|
28
|
+
isSameOrAfter: (other: SemverInput) => boolean;
|
|
29
|
+
isBefore: (other: SemverInput) => boolean;
|
|
30
|
+
isSameOrBefore: (other: SemverInput) => boolean;
|
|
31
|
+
isSame: (other: SemverInput) => boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Returns 1 if this > other
|
|
34
|
+
* returns 0 if they are equal
|
|
35
|
+
* returns -1 if this < other
|
|
36
|
+
*/
|
|
37
|
+
cmp(other: SemverInput): -1 | 0 | 1;
|
|
38
|
+
toJSON: () => string;
|
|
39
|
+
toString(): string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Shortcut for Semver.of(input)
|
|
43
|
+
*/
|
|
44
|
+
export declare function _semver(input: SemverInput): Semver;
|
package/dist/semver.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports._semver = exports.Semver = void 0;
|
|
4
|
+
const range_1 = require("./array/range");
|
|
5
|
+
const assert_1 = require("./error/assert");
|
|
6
|
+
/**
|
|
7
|
+
* Simple Semver implementation.
|
|
8
|
+
*
|
|
9
|
+
* Suitable for Browser usage, unlike npm `semver` which is Node-targeted and simply too big for the Browser.
|
|
10
|
+
*
|
|
11
|
+
* Parsing algorithm is simple:
|
|
12
|
+
* 1. Split by `.`
|
|
13
|
+
* 2. parseInt each of 3 tokens, set to 0 if falsy
|
|
14
|
+
*
|
|
15
|
+
* toString returns `major.minor.patch`
|
|
16
|
+
* Missing tokens are replaced with 0.
|
|
17
|
+
*
|
|
18
|
+
* _semver('1').toString() === '1.0.0'
|
|
19
|
+
*
|
|
20
|
+
* @experimental
|
|
21
|
+
*/
|
|
22
|
+
class Semver {
|
|
23
|
+
constructor(tokens) {
|
|
24
|
+
this.tokens = tokens;
|
|
25
|
+
this.isAfter = (other) => this.cmp(other) > 0;
|
|
26
|
+
this.isSameOrAfter = (other) => this.cmp(other) >= 0;
|
|
27
|
+
this.isBefore = (other) => this.cmp(other) < 0;
|
|
28
|
+
this.isSameOrBefore = (other) => this.cmp(other) <= 0;
|
|
29
|
+
this.isSame = (other) => this.cmp(other) === 0;
|
|
30
|
+
this.toJSON = () => this.toString();
|
|
31
|
+
}
|
|
32
|
+
get major() {
|
|
33
|
+
return this.tokens[0];
|
|
34
|
+
}
|
|
35
|
+
get minor() {
|
|
36
|
+
return this.tokens[1];
|
|
37
|
+
}
|
|
38
|
+
get patch() {
|
|
39
|
+
return this.tokens[2];
|
|
40
|
+
}
|
|
41
|
+
static of(input) {
|
|
42
|
+
const s = this.parseOrNull(input);
|
|
43
|
+
(0, assert_1._assert)(s !== null, `Cannot parse "${input}" into Semver`, {
|
|
44
|
+
userFriendly: true,
|
|
45
|
+
input,
|
|
46
|
+
});
|
|
47
|
+
return s;
|
|
48
|
+
}
|
|
49
|
+
static parseOrNull(input) {
|
|
50
|
+
if (!input)
|
|
51
|
+
return null;
|
|
52
|
+
if (input instanceof Semver)
|
|
53
|
+
return input;
|
|
54
|
+
const t = input.split('.');
|
|
55
|
+
return new Semver((0, range_1._range)(3).map(i => parseInt(t[i]) || 0));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Returns 1 if this > other
|
|
59
|
+
* returns 0 if they are equal
|
|
60
|
+
* returns -1 if this < other
|
|
61
|
+
*/
|
|
62
|
+
cmp(other) {
|
|
63
|
+
const { tokens } = Semver.of(other);
|
|
64
|
+
for (let i = 0; i < 3; i++) {
|
|
65
|
+
if (this.tokens[i] < tokens[i])
|
|
66
|
+
return -1;
|
|
67
|
+
if (this.tokens[i] > tokens[i])
|
|
68
|
+
return 1;
|
|
69
|
+
}
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
72
|
+
toString() {
|
|
73
|
+
return this.tokens.join('.');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
exports.Semver = Semver;
|
|
77
|
+
/**
|
|
78
|
+
* Shortcut for Semver.of(input)
|
|
79
|
+
*/
|
|
80
|
+
function _semver(input) {
|
|
81
|
+
return Semver.of(input);
|
|
82
|
+
}
|
|
83
|
+
exports._semver = _semver;
|
|
@@ -20,16 +20,14 @@ export class LocalDate {
|
|
|
20
20
|
*/
|
|
21
21
|
static of(d) {
|
|
22
22
|
const t = this.parseOrNull(d);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
23
|
+
_assert(t !== null, `Cannot parse "${d}" into LocalDate`, {
|
|
24
|
+
input: d,
|
|
25
|
+
});
|
|
26
26
|
return t;
|
|
27
27
|
}
|
|
28
28
|
static parseCompact(d) {
|
|
29
29
|
const [year, month, day] = [d.slice(0, 4), d.slice(4, 2), d.slice(6, 2)].map(Number);
|
|
30
|
-
|
|
31
|
-
throw new Error(`Cannot parse "${d}" into LocalDate`);
|
|
32
|
-
}
|
|
30
|
+
_assert(day && month && year, `Cannot parse "${d}" into LocalDate`);
|
|
33
31
|
return new LocalDate(year, month, day);
|
|
34
32
|
}
|
|
35
33
|
static fromDate(d) {
|
|
@@ -30,9 +30,9 @@ export class LocalTime {
|
|
|
30
30
|
*/
|
|
31
31
|
static of(d) {
|
|
32
32
|
const t = this.parseOrNull(d);
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
33
|
+
_assert(t !== null, `Cannot parse "${d}" into LocalTime`, {
|
|
34
|
+
input: d,
|
|
35
|
+
});
|
|
36
36
|
return t;
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
@@ -79,9 +79,9 @@ export class LocalTime {
|
|
|
79
79
|
if (d instanceof Date)
|
|
80
80
|
return d;
|
|
81
81
|
const date = typeof d === 'number' ? new Date(d * 1000) : new Date(d);
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
82
|
+
_assert(!isNaN(date.getDate()), `Cannot parse "${d}" to Date`, {
|
|
83
|
+
input: d,
|
|
84
|
+
});
|
|
85
85
|
return date;
|
|
86
86
|
}
|
|
87
87
|
static parseToUnixTimestamp(d) {
|
|
@@ -90,9 +90,9 @@ export class LocalTime {
|
|
|
90
90
|
if (d instanceof LocalTime)
|
|
91
91
|
return d.unix();
|
|
92
92
|
const date = d instanceof Date ? d : new Date(d);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
93
|
+
_assert(!isNaN(date.getDate()), `Cannot parse "${d}" to UnixTimestamp`, {
|
|
94
|
+
input: d,
|
|
95
|
+
});
|
|
96
96
|
return date.valueOf() / 1000;
|
|
97
97
|
}
|
|
98
98
|
static isValid(d) {
|
|
@@ -168,8 +168,7 @@ export class LocalTime {
|
|
|
168
168
|
if (v === undefined) {
|
|
169
169
|
return dow;
|
|
170
170
|
}
|
|
171
|
-
|
|
172
|
-
throw new Error(`Invalid dayOfWeek: ${v}`);
|
|
171
|
+
_assert(VALID_DAYS_OF_WEEK.has(v), `Invalid dayOfWeek: ${v}`);
|
|
173
172
|
return this.add(v - dow, 'day');
|
|
174
173
|
}
|
|
175
174
|
hour(v) {
|
package/dist-esm/index.js
CHANGED
|
@@ -81,6 +81,7 @@ export * from './http/fetcher.model';
|
|
|
81
81
|
export * from './string/hash.util';
|
|
82
82
|
export * from './env/buildInfo';
|
|
83
83
|
export * from './form.util';
|
|
84
|
+
export * from './semver';
|
|
84
85
|
export * from './zod/zod.util';
|
|
85
86
|
export * from './zod/zod.shared.schemas';
|
|
86
87
|
import { z, ZodSchema, ZodError } from 'zod';
|
package/dist-esm/is.util.js
CHANGED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { _range } from './array/range';
|
|
2
|
+
import { _assert } from './error/assert';
|
|
3
|
+
/**
|
|
4
|
+
* Simple Semver implementation.
|
|
5
|
+
*
|
|
6
|
+
* Suitable for Browser usage, unlike npm `semver` which is Node-targeted and simply too big for the Browser.
|
|
7
|
+
*
|
|
8
|
+
* Parsing algorithm is simple:
|
|
9
|
+
* 1. Split by `.`
|
|
10
|
+
* 2. parseInt each of 3 tokens, set to 0 if falsy
|
|
11
|
+
*
|
|
12
|
+
* toString returns `major.minor.patch`
|
|
13
|
+
* Missing tokens are replaced with 0.
|
|
14
|
+
*
|
|
15
|
+
* _semver('1').toString() === '1.0.0'
|
|
16
|
+
*
|
|
17
|
+
* @experimental
|
|
18
|
+
*/
|
|
19
|
+
export class Semver {
|
|
20
|
+
constructor(tokens) {
|
|
21
|
+
this.tokens = tokens;
|
|
22
|
+
this.isAfter = (other) => this.cmp(other) > 0;
|
|
23
|
+
this.isSameOrAfter = (other) => this.cmp(other) >= 0;
|
|
24
|
+
this.isBefore = (other) => this.cmp(other) < 0;
|
|
25
|
+
this.isSameOrBefore = (other) => this.cmp(other) <= 0;
|
|
26
|
+
this.isSame = (other) => this.cmp(other) === 0;
|
|
27
|
+
this.toJSON = () => this.toString();
|
|
28
|
+
}
|
|
29
|
+
get major() {
|
|
30
|
+
return this.tokens[0];
|
|
31
|
+
}
|
|
32
|
+
get minor() {
|
|
33
|
+
return this.tokens[1];
|
|
34
|
+
}
|
|
35
|
+
get patch() {
|
|
36
|
+
return this.tokens[2];
|
|
37
|
+
}
|
|
38
|
+
static of(input) {
|
|
39
|
+
const s = this.parseOrNull(input);
|
|
40
|
+
_assert(s !== null, `Cannot parse "${input}" into Semver`, {
|
|
41
|
+
userFriendly: true,
|
|
42
|
+
input,
|
|
43
|
+
});
|
|
44
|
+
return s;
|
|
45
|
+
}
|
|
46
|
+
static parseOrNull(input) {
|
|
47
|
+
if (!input)
|
|
48
|
+
return null;
|
|
49
|
+
if (input instanceof Semver)
|
|
50
|
+
return input;
|
|
51
|
+
const t = input.split('.');
|
|
52
|
+
return new Semver(_range(3).map(i => parseInt(t[i]) || 0));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Returns 1 if this > other
|
|
56
|
+
* returns 0 if they are equal
|
|
57
|
+
* returns -1 if this < other
|
|
58
|
+
*/
|
|
59
|
+
cmp(other) {
|
|
60
|
+
const { tokens } = Semver.of(other);
|
|
61
|
+
for (let i = 0; i < 3; i++) {
|
|
62
|
+
if (this.tokens[i] < tokens[i])
|
|
63
|
+
return -1;
|
|
64
|
+
if (this.tokens[i] > tokens[i])
|
|
65
|
+
return 1;
|
|
66
|
+
}
|
|
67
|
+
return 0;
|
|
68
|
+
}
|
|
69
|
+
toString() {
|
|
70
|
+
return this.tokens.join('.');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Shortcut for Semver.of(input)
|
|
75
|
+
*/
|
|
76
|
+
export function _semver(input) {
|
|
77
|
+
return Semver.of(input);
|
|
78
|
+
}
|
package/package.json
CHANGED
|
@@ -38,9 +38,9 @@ export class LocalDate {
|
|
|
38
38
|
static of(d: LocalDateInput): LocalDate {
|
|
39
39
|
const t = this.parseOrNull(d)
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
41
|
+
_assert(t !== null, `Cannot parse "${d}" into LocalDate`, {
|
|
42
|
+
input: d,
|
|
43
|
+
})
|
|
44
44
|
|
|
45
45
|
return t
|
|
46
46
|
}
|
|
@@ -48,9 +48,7 @@ export class LocalDate {
|
|
|
48
48
|
static parseCompact(d: string): LocalDate {
|
|
49
49
|
const [year, month, day] = [d.slice(0, 4), d.slice(4, 2), d.slice(6, 2)].map(Number)
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
throw new Error(`Cannot parse "${d}" into LocalDate`)
|
|
53
|
-
}
|
|
51
|
+
_assert(day && month && year, `Cannot parse "${d}" into LocalDate`)
|
|
54
52
|
|
|
55
53
|
return new LocalDate(year, month, day)
|
|
56
54
|
}
|
|
@@ -53,9 +53,9 @@ export class LocalTime {
|
|
|
53
53
|
static of(d: LocalTimeInput): LocalTime {
|
|
54
54
|
const t = this.parseOrNull(d)
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
56
|
+
_assert(t !== null, `Cannot parse "${d}" into LocalTime`, {
|
|
57
|
+
input: d,
|
|
58
|
+
})
|
|
59
59
|
|
|
60
60
|
return t
|
|
61
61
|
}
|
|
@@ -106,9 +106,9 @@ export class LocalTime {
|
|
|
106
106
|
|
|
107
107
|
const date = typeof d === 'number' ? new Date(d * 1000) : new Date(d)
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
109
|
+
_assert(!isNaN(date.getDate()), `Cannot parse "${d}" to Date`, {
|
|
110
|
+
input: d,
|
|
111
|
+
})
|
|
112
112
|
|
|
113
113
|
return date
|
|
114
114
|
}
|
|
@@ -119,9 +119,9 @@ export class LocalTime {
|
|
|
119
119
|
|
|
120
120
|
const date = d instanceof Date ? d : new Date(d)
|
|
121
121
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
122
|
+
_assert(!isNaN(date.getDate()), `Cannot parse "${d}" to UnixTimestamp`, {
|
|
123
|
+
input: d,
|
|
124
|
+
})
|
|
125
125
|
|
|
126
126
|
return date.valueOf() / 1000
|
|
127
127
|
}
|
|
@@ -220,7 +220,7 @@ export class LocalTime {
|
|
|
220
220
|
return dow
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
|
|
223
|
+
_assert(VALID_DAYS_OF_WEEK.has(v), `Invalid dayOfWeek: ${v}`)
|
|
224
224
|
|
|
225
225
|
return this.add(v - dow, 'day')
|
|
226
226
|
}
|
package/src/index.ts
CHANGED
|
@@ -81,6 +81,7 @@ export * from './http/fetcher.model'
|
|
|
81
81
|
export * from './string/hash.util'
|
|
82
82
|
export * from './env/buildInfo'
|
|
83
83
|
export * from './form.util'
|
|
84
|
+
export * from './semver'
|
|
84
85
|
export * from './zod/zod.util'
|
|
85
86
|
export * from './zod/zod.shared.schemas'
|
|
86
87
|
import { z, ZodSchema, ZodError, ZodIssue } from 'zod'
|
package/src/is.util.ts
CHANGED
package/src/semver.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { _range } from './array/range'
|
|
2
|
+
import { _assert } from './error/assert'
|
|
3
|
+
|
|
4
|
+
export type SemverInput = string | Semver
|
|
5
|
+
export type SemverTokens = [major: number, minor: number, patch: number]
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Simple Semver implementation.
|
|
9
|
+
*
|
|
10
|
+
* Suitable for Browser usage, unlike npm `semver` which is Node-targeted and simply too big for the Browser.
|
|
11
|
+
*
|
|
12
|
+
* Parsing algorithm is simple:
|
|
13
|
+
* 1. Split by `.`
|
|
14
|
+
* 2. parseInt each of 3 tokens, set to 0 if falsy
|
|
15
|
+
*
|
|
16
|
+
* toString returns `major.minor.patch`
|
|
17
|
+
* Missing tokens are replaced with 0.
|
|
18
|
+
*
|
|
19
|
+
* _semver('1').toString() === '1.0.0'
|
|
20
|
+
*
|
|
21
|
+
* @experimental
|
|
22
|
+
*/
|
|
23
|
+
export class Semver {
|
|
24
|
+
private constructor(public tokens: SemverTokens) {}
|
|
25
|
+
|
|
26
|
+
get major(): number {
|
|
27
|
+
return this.tokens[0]
|
|
28
|
+
}
|
|
29
|
+
get minor(): number {
|
|
30
|
+
return this.tokens[1]
|
|
31
|
+
}
|
|
32
|
+
get patch(): number {
|
|
33
|
+
return this.tokens[2]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static of(input: SemverInput): Semver {
|
|
37
|
+
const s = this.parseOrNull(input)
|
|
38
|
+
|
|
39
|
+
_assert(s !== null, `Cannot parse "${input}" into Semver`, {
|
|
40
|
+
userFriendly: true,
|
|
41
|
+
input,
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
return s
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static parseOrNull(input: SemverInput | undefined | null): Semver | null {
|
|
48
|
+
if (!input) return null
|
|
49
|
+
if (input instanceof Semver) return input
|
|
50
|
+
|
|
51
|
+
const t = input.split('.')
|
|
52
|
+
return new Semver(_range(3).map(i => parseInt(t[i]!) || 0) as SemverTokens)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
isAfter = (other: SemverInput): boolean => this.cmp(other) > 0
|
|
56
|
+
isSameOrAfter = (other: SemverInput): boolean => this.cmp(other) >= 0
|
|
57
|
+
isBefore = (other: SemverInput): boolean => this.cmp(other) < 0
|
|
58
|
+
isSameOrBefore = (other: SemverInput): boolean => this.cmp(other) <= 0
|
|
59
|
+
isSame = (other: SemverInput): boolean => this.cmp(other) === 0
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Returns 1 if this > other
|
|
63
|
+
* returns 0 if they are equal
|
|
64
|
+
* returns -1 if this < other
|
|
65
|
+
*/
|
|
66
|
+
cmp(other: SemverInput): -1 | 0 | 1 {
|
|
67
|
+
const { tokens } = Semver.of(other)
|
|
68
|
+
for (let i = 0; i < 3; i++) {
|
|
69
|
+
if (this.tokens[i]! < tokens[i]!) return -1
|
|
70
|
+
if (this.tokens[i]! > tokens[i]!) return 1
|
|
71
|
+
}
|
|
72
|
+
return 0
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
toJSON = (): string => this.toString()
|
|
76
|
+
|
|
77
|
+
toString(): string {
|
|
78
|
+
return this.tokens.join('.')
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Shortcut for Semver.of(input)
|
|
84
|
+
*/
|
|
85
|
+
export function _semver(input: SemverInput): Semver {
|
|
86
|
+
return Semver.of(input)
|
|
87
|
+
}
|