mybase 1.1.51 → 1.1.53
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/jest.config.js +1 -0
- package/package.json +1 -1
- package/ts/index.d.ts +1 -0
- package/ts/index.js +1 -0
- package/ts/index.ts +1 -1
- package/ts/models/DateIterator.d.ts +33 -0
- package/ts/models/DateIterator.js +76 -0
- package/ts/models/DateIterator.test.ts +149 -0
- package/ts/models/DateIterator.ts +80 -0
- package/ts/models/OTPGenerator.test.ts +1 -1
package/jest.config.js
CHANGED
package/package.json
CHANGED
package/ts/index.d.ts
CHANGED
package/ts/index.js
CHANGED
|
@@ -49,4 +49,5 @@ __exportStar(require("./models/Timespan"), exports);
|
|
|
49
49
|
__exportStar(require("./models/IPAddress"), exports);
|
|
50
50
|
__exportStar(require("./models/OTPGenerator"), exports);
|
|
51
51
|
__exportStar(require("./models/Interfaces"), exports);
|
|
52
|
+
__exportStar(require("./models/DateIterator"), exports);
|
|
52
53
|
//# sourceMappingURL=index.js.map
|
package/ts/index.ts
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Unixtime } from "./Unixtime";
|
|
2
|
+
/**
|
|
3
|
+
* Iterates day-by-day backwards from `start` toward `end` (end-exclusive),
|
|
4
|
+
* emitting each date as a `yyyy{sep}mm{sep}dd` string.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const it = new DateIterator(Unixtime.now(), Unixtime.now().addDays(-5))
|
|
8
|
+
* it.next() // "20260417"
|
|
9
|
+
* it.next() // "20260416"
|
|
10
|
+
* // ...
|
|
11
|
+
* it.next() // null
|
|
12
|
+
*
|
|
13
|
+
* @example separator
|
|
14
|
+
* new DateIterator(start, end, "-").toArray()
|
|
15
|
+
* // ["2026-04-17", "2026-04-16", ...]
|
|
16
|
+
*
|
|
17
|
+
* @example for..of
|
|
18
|
+
* for (const d of new DateIterator(start, end, "/")) console.log(d)
|
|
19
|
+
*/
|
|
20
|
+
export declare class DateIterator implements Iterable<string> {
|
|
21
|
+
private readonly start;
|
|
22
|
+
private readonly end;
|
|
23
|
+
private readonly separator;
|
|
24
|
+
private cursor;
|
|
25
|
+
constructor(start: Unixtime, end: Unixtime, separator?: string);
|
|
26
|
+
/** Returns the next formatted date going backwards, or `null` when exhausted. */
|
|
27
|
+
next(): string | null;
|
|
28
|
+
/** Reset the iterator so it can be consumed again from `start`. */
|
|
29
|
+
reset(): this;
|
|
30
|
+
/** Collect all remaining dates into an array. */
|
|
31
|
+
toArray(): string[];
|
|
32
|
+
[Symbol.iterator](): Iterator<string>;
|
|
33
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DateIterator = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Iterates day-by-day backwards from `start` toward `end` (end-exclusive),
|
|
6
|
+
* emitting each date as a `yyyy{sep}mm{sep}dd` string.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const it = new DateIterator(Unixtime.now(), Unixtime.now().addDays(-5))
|
|
10
|
+
* it.next() // "20260417"
|
|
11
|
+
* it.next() // "20260416"
|
|
12
|
+
* // ...
|
|
13
|
+
* it.next() // null
|
|
14
|
+
*
|
|
15
|
+
* @example separator
|
|
16
|
+
* new DateIterator(start, end, "-").toArray()
|
|
17
|
+
* // ["2026-04-17", "2026-04-16", ...]
|
|
18
|
+
*
|
|
19
|
+
* @example for..of
|
|
20
|
+
* for (const d of new DateIterator(start, end, "/")) console.log(d)
|
|
21
|
+
*/
|
|
22
|
+
class DateIterator {
|
|
23
|
+
constructor(start, end, separator = "") {
|
|
24
|
+
if (start.lessThan(end)) {
|
|
25
|
+
throw new Error('DateIterator: `start` must be newer than or equal to `end`');
|
|
26
|
+
}
|
|
27
|
+
// Defensive clones: callers' instances must not be mutated, and
|
|
28
|
+
// Unixtime.addDays() mutates the underlying Date.
|
|
29
|
+
this.start = start.clone();
|
|
30
|
+
this.end = end.clone();
|
|
31
|
+
this.separator = separator;
|
|
32
|
+
this.cursor = this.start.clone();
|
|
33
|
+
}
|
|
34
|
+
/** Returns the next formatted date going backwards, or `null` when exhausted. */
|
|
35
|
+
next() {
|
|
36
|
+
if (this.cursor === null)
|
|
37
|
+
return null;
|
|
38
|
+
if (!this.cursor.greaterThan(this.end)) {
|
|
39
|
+
this.cursor = null;
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const value = this.cursor.yyyymmdd(this.separator);
|
|
43
|
+
this.cursor.addDays(-1);
|
|
44
|
+
return value;
|
|
45
|
+
}
|
|
46
|
+
/** Reset the iterator so it can be consumed again from `start`. */
|
|
47
|
+
reset() {
|
|
48
|
+
this.cursor = this.start.clone();
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
/** Collect all remaining dates into an array. */
|
|
52
|
+
toArray() {
|
|
53
|
+
const out = [];
|
|
54
|
+
let d;
|
|
55
|
+
while ((d = this.next()) !== null)
|
|
56
|
+
out.push(d);
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
59
|
+
[Symbol.iterator]() {
|
|
60
|
+
let cursor = this.start.clone();
|
|
61
|
+
const end = this.end;
|
|
62
|
+
const sep = this.separator;
|
|
63
|
+
return {
|
|
64
|
+
next() {
|
|
65
|
+
if (cursor === null || !cursor.greaterThan(end)) {
|
|
66
|
+
return { value: undefined, done: true };
|
|
67
|
+
}
|
|
68
|
+
const value = cursor.yyyymmdd(sep);
|
|
69
|
+
cursor.addDays(-1);
|
|
70
|
+
return { value, done: false };
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.DateIterator = DateIterator;
|
|
76
|
+
//# sourceMappingURL=DateIterator.js.map
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { DateIterator } from './DateIterator';
|
|
2
|
+
import { Unixtime } from './Unixtime';
|
|
3
|
+
|
|
4
|
+
describe('DateIterator', () => {
|
|
5
|
+
const start = () => Unixtime.fromYYYYMMDD('20240110');
|
|
6
|
+
const end = () => Unixtime.fromYYYYMMDD('20240105');
|
|
7
|
+
|
|
8
|
+
it('should iterate backwards day-by-day (end-exclusive) with default separator', () => {
|
|
9
|
+
const it = new DateIterator(start(), end());
|
|
10
|
+
expect(it.toArray()).toEqual([
|
|
11
|
+
'20240110',
|
|
12
|
+
'20240109',
|
|
13
|
+
'20240108',
|
|
14
|
+
'20240107',
|
|
15
|
+
'20240106',
|
|
16
|
+
]);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should honor a custom separator', () => {
|
|
20
|
+
const it = new DateIterator(start(), end(), '-');
|
|
21
|
+
expect(it.toArray()).toEqual([
|
|
22
|
+
'2024-01-10',
|
|
23
|
+
'2024-01-09',
|
|
24
|
+
'2024-01-08',
|
|
25
|
+
'2024-01-07',
|
|
26
|
+
'2024-01-06',
|
|
27
|
+
]);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should honor a slash separator', () => {
|
|
31
|
+
const it = new DateIterator(start(), end(), '/');
|
|
32
|
+
expect(it.toArray()).toEqual([
|
|
33
|
+
'2024/01/10',
|
|
34
|
+
'2024/01/09',
|
|
35
|
+
'2024/01/08',
|
|
36
|
+
'2024/01/07',
|
|
37
|
+
'2024/01/06',
|
|
38
|
+
]);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('next() should return null when exhausted', () => {
|
|
42
|
+
const s = Unixtime.fromYYYYMMDD('20240103');
|
|
43
|
+
const e = Unixtime.fromYYYYMMDD('20240101');
|
|
44
|
+
const it = new DateIterator(s, e);
|
|
45
|
+
expect(it.next()).toEqual('20240103');
|
|
46
|
+
expect(it.next()).toEqual('20240102');
|
|
47
|
+
expect(it.next()).toBeNull();
|
|
48
|
+
expect(it.next()).toBeNull();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should return empty array when start equals end (end-exclusive)', () => {
|
|
52
|
+
const s = Unixtime.fromYYYYMMDD('20240105');
|
|
53
|
+
const e = Unixtime.fromYYYYMMDD('20240105');
|
|
54
|
+
const it = new DateIterator(s, e);
|
|
55
|
+
expect(it.toArray()).toEqual([]);
|
|
56
|
+
expect(it.next()).toBeNull();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should throw when start is older than end', () => {
|
|
60
|
+
const s = Unixtime.fromYYYYMMDD('20240101');
|
|
61
|
+
const e = Unixtime.fromYYYYMMDD('20240110');
|
|
62
|
+
expect(() => new DateIterator(s, e)).toThrow(
|
|
63
|
+
'DateIterator: `start` must be newer than or equal to `end`'
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should not mutate the caller-supplied Unixtime instances', () => {
|
|
68
|
+
const s = Unixtime.fromYYYYMMDD('20240110');
|
|
69
|
+
const e = Unixtime.fromYYYYMMDD('20240105');
|
|
70
|
+
const sBefore = s.toLongUnixtime();
|
|
71
|
+
const eBefore = e.toLongUnixtime();
|
|
72
|
+
const it = new DateIterator(s, e);
|
|
73
|
+
it.toArray();
|
|
74
|
+
expect(s.toLongUnixtime()).toEqual(sBefore);
|
|
75
|
+
expect(e.toLongUnixtime()).toEqual(eBefore);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('reset() should allow the iterator to be consumed again', () => {
|
|
79
|
+
const it = new DateIterator(start(), end());
|
|
80
|
+
const first = it.toArray();
|
|
81
|
+
expect(it.next()).toBeNull();
|
|
82
|
+
it.reset();
|
|
83
|
+
const second = it.toArray();
|
|
84
|
+
expect(second).toEqual(first);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('reset() should return the iterator for chaining', () => {
|
|
88
|
+
const it = new DateIterator(start(), end());
|
|
89
|
+
expect(it.reset()).toBe(it);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should be iterable via for..of', () => {
|
|
93
|
+
const it = new DateIterator(start(), end(), '-');
|
|
94
|
+
const out: string[] = [];
|
|
95
|
+
for (const d of it) out.push(d);
|
|
96
|
+
expect(out).toEqual([
|
|
97
|
+
'2024-01-10',
|
|
98
|
+
'2024-01-09',
|
|
99
|
+
'2024-01-08',
|
|
100
|
+
'2024-01-07',
|
|
101
|
+
'2024-01-06',
|
|
102
|
+
]);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('for..of should be independent of next()/toArray() cursor', () => {
|
|
106
|
+
const it = new DateIterator(start(), end());
|
|
107
|
+
expect(it.next()).toEqual('20240110');
|
|
108
|
+
const collected: string[] = [];
|
|
109
|
+
for (const d of it) collected.push(d);
|
|
110
|
+
expect(collected).toEqual([
|
|
111
|
+
'20240110',
|
|
112
|
+
'20240109',
|
|
113
|
+
'20240108',
|
|
114
|
+
'20240107',
|
|
115
|
+
'20240106',
|
|
116
|
+
]);
|
|
117
|
+
expect(it.next()).toEqual('20240109');
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('should support spread syntax', () => {
|
|
121
|
+
const it = new DateIterator(
|
|
122
|
+
Unixtime.fromYYYYMMDD('20240103'),
|
|
123
|
+
Unixtime.fromYYYYMMDD('20240101')
|
|
124
|
+
);
|
|
125
|
+
expect([...it]).toEqual(['20240103', '20240102']);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('should cross month boundaries correctly', () => {
|
|
129
|
+
const s = Unixtime.fromYYYYMMDD('20240302');
|
|
130
|
+
const e = Unixtime.fromYYYYMMDD('20240227');
|
|
131
|
+
const it = new DateIterator(s, e, '-');
|
|
132
|
+
expect(it.toArray()).toEqual([
|
|
133
|
+
'2024-03-02',
|
|
134
|
+
'2024-03-01',
|
|
135
|
+
'2024-02-29',
|
|
136
|
+
'2024-02-28',
|
|
137
|
+
]);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should produce N entries for a span of N+1 days (end-exclusive)', () => {
|
|
141
|
+
const s = Unixtime.fromYYYYMMDD('20240620');
|
|
142
|
+
const e = Unixtime.fromYYYYMMDD('20240610');
|
|
143
|
+
const it = new DateIterator(s, e);
|
|
144
|
+
const arr = it.toArray();
|
|
145
|
+
expect(arr.length).toEqual(10);
|
|
146
|
+
expect(arr[0]).toEqual('20240620');
|
|
147
|
+
expect(arr[arr.length - 1]).toEqual('20240611');
|
|
148
|
+
});
|
|
149
|
+
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Unixtime } from "./Unixtime"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Iterates day-by-day backwards from `start` toward `end` (end-exclusive),
|
|
5
|
+
* emitting each date as a `yyyy{sep}mm{sep}dd` string.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const it = new DateIterator(Unixtime.now(), Unixtime.now().addDays(-5))
|
|
9
|
+
* it.next() // "20260417"
|
|
10
|
+
* it.next() // "20260416"
|
|
11
|
+
* // ...
|
|
12
|
+
* it.next() // null
|
|
13
|
+
*
|
|
14
|
+
* @example separator
|
|
15
|
+
* new DateIterator(start, end, "-").toArray()
|
|
16
|
+
* // ["2026-04-17", "2026-04-16", ...]
|
|
17
|
+
*
|
|
18
|
+
* @example for..of
|
|
19
|
+
* for (const d of new DateIterator(start, end, "/")) console.log(d)
|
|
20
|
+
*/
|
|
21
|
+
export class DateIterator implements Iterable<string> {
|
|
22
|
+
private readonly start: Unixtime
|
|
23
|
+
private readonly end: Unixtime
|
|
24
|
+
private readonly separator: string
|
|
25
|
+
private cursor: Unixtime | null
|
|
26
|
+
|
|
27
|
+
constructor(start: Unixtime, end: Unixtime, separator: string = "") {
|
|
28
|
+
if (start.lessThan(end)) {
|
|
29
|
+
throw new Error('DateIterator: `start` must be newer than or equal to `end`')
|
|
30
|
+
}
|
|
31
|
+
// Defensive clones: callers' instances must not be mutated, and
|
|
32
|
+
// Unixtime.addDays() mutates the underlying Date.
|
|
33
|
+
this.start = start.clone()
|
|
34
|
+
this.end = end.clone()
|
|
35
|
+
this.separator = separator
|
|
36
|
+
this.cursor = this.start.clone()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Returns the next formatted date going backwards, or `null` when exhausted. */
|
|
40
|
+
next(): string | null {
|
|
41
|
+
if (this.cursor === null) return null
|
|
42
|
+
if (!this.cursor.greaterThan(this.end)) {
|
|
43
|
+
this.cursor = null
|
|
44
|
+
return null
|
|
45
|
+
}
|
|
46
|
+
const value = this.cursor.yyyymmdd(this.separator)
|
|
47
|
+
this.cursor.addDays(-1)
|
|
48
|
+
return value
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Reset the iterator so it can be consumed again from `start`. */
|
|
52
|
+
reset(): this {
|
|
53
|
+
this.cursor = this.start.clone()
|
|
54
|
+
return this
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Collect all remaining dates into an array. */
|
|
58
|
+
toArray(): string[] {
|
|
59
|
+
const out: string[] = []
|
|
60
|
+
let d: string | null
|
|
61
|
+
while ((d = this.next()) !== null) out.push(d)
|
|
62
|
+
return out
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
[Symbol.iterator](): Iterator<string> {
|
|
66
|
+
let cursor: Unixtime | null = this.start.clone()
|
|
67
|
+
const end = this.end
|
|
68
|
+
const sep = this.separator
|
|
69
|
+
return {
|
|
70
|
+
next(): IteratorResult<string> {
|
|
71
|
+
if (cursor === null || !cursor.greaterThan(end)) {
|
|
72
|
+
return { value: undefined as unknown as string, done: true }
|
|
73
|
+
}
|
|
74
|
+
const value = cursor.yyyymmdd(sep)
|
|
75
|
+
cursor.addDays(-1)
|
|
76
|
+
return { value, done: false }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -15,7 +15,7 @@ describe('OTPGenerator', () => {
|
|
|
15
15
|
it('should generate different OTPs in milliseconds', async () => {
|
|
16
16
|
const otpGenerator = new OTPGenerator(passkey, 5);
|
|
17
17
|
const otp1 = otpGenerator.generateOTP()
|
|
18
|
-
await wait(
|
|
18
|
+
await wait(3/1000);
|
|
19
19
|
const otp2 = otpGenerator.generateOTP();
|
|
20
20
|
expect(otp1).not.toBe(otp2);
|
|
21
21
|
})
|