ts-cache-mongoose 2.0.0 → 2.1.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 +14 -15
- package/dist/index.cjs +84 -118
- package/dist/index.d.cts +48 -10
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +48 -10
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +84 -118
- package/dist/nest/index.cjs +3 -1
- package/dist/nest/index.mjs +3 -1
- package/package.json +2 -2
- package/src/cache/Cache.ts +4 -4
- package/src/cache/engine/MemoryCacheEngine.ts +3 -3
- package/src/cache/engine/RedisCacheEngine.ts +3 -3
- package/src/extend/aggregate.ts +5 -6
- package/src/extend/query.ts +5 -6
- package/src/index.ts +7 -7
- package/src/ms.ts +46 -35
- package/src/types.ts +4 -3
- package/tests/ms.test.ts +69 -49
- package/tsconfig.json +2 -3
package/src/ms.ts
CHANGED
|
@@ -4,52 +4,63 @@ const h = m * 60
|
|
|
4
4
|
const d = h * 24
|
|
5
5
|
const w = d * 7
|
|
6
6
|
const y = d * 365.25
|
|
7
|
+
const mo = y / 12
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
const RE = /^(-?(?:\d+)?\.?\d+)\s*(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i
|
|
10
|
-
|
|
11
|
-
const UNITS: Record<string, number> = {
|
|
12
|
-
years: y,
|
|
13
|
-
year: y,
|
|
14
|
-
yrs: y,
|
|
15
|
-
yr: y,
|
|
16
|
-
y,
|
|
17
|
-
weeks: w,
|
|
18
|
-
week: w,
|
|
19
|
-
w,
|
|
20
|
-
days: d,
|
|
21
|
-
day: d,
|
|
22
|
-
d,
|
|
23
|
-
hours: h,
|
|
24
|
-
hour: h,
|
|
25
|
-
hrs: h,
|
|
26
|
-
hr: h,
|
|
27
|
-
h,
|
|
28
|
-
minutes: m,
|
|
29
|
-
minute: m,
|
|
30
|
-
mins: m,
|
|
31
|
-
min: m,
|
|
32
|
-
m,
|
|
33
|
-
seconds: s,
|
|
34
|
-
second: s,
|
|
35
|
-
secs: s,
|
|
36
|
-
sec: s,
|
|
37
|
-
s,
|
|
9
|
+
export const UNITS = {
|
|
38
10
|
milliseconds: 1,
|
|
39
11
|
millisecond: 1,
|
|
40
12
|
msecs: 1,
|
|
41
13
|
msec: 1,
|
|
42
14
|
ms: 1,
|
|
43
|
-
|
|
15
|
+
seconds: s,
|
|
16
|
+
second: s,
|
|
17
|
+
secs: s,
|
|
18
|
+
sec: s,
|
|
19
|
+
s,
|
|
20
|
+
minutes: m,
|
|
21
|
+
minute: m,
|
|
22
|
+
mins: m,
|
|
23
|
+
min: m,
|
|
24
|
+
m,
|
|
25
|
+
hours: h,
|
|
26
|
+
hour: h,
|
|
27
|
+
hrs: h,
|
|
28
|
+
hr: h,
|
|
29
|
+
h,
|
|
30
|
+
days: d,
|
|
31
|
+
day: d,
|
|
32
|
+
d,
|
|
33
|
+
weeks: w,
|
|
34
|
+
week: w,
|
|
35
|
+
w,
|
|
36
|
+
months: mo,
|
|
37
|
+
month: mo,
|
|
38
|
+
mo,
|
|
39
|
+
years: y,
|
|
40
|
+
year: y,
|
|
41
|
+
yrs: y,
|
|
42
|
+
yr: y,
|
|
43
|
+
y,
|
|
44
|
+
} as const satisfies Record<string, number>
|
|
45
|
+
|
|
46
|
+
export type Unit = keyof typeof UNITS
|
|
47
|
+
|
|
48
|
+
export type Duration = number | `${number}` | `${number}${Unit}` | `${number} ${Unit}`
|
|
49
|
+
|
|
50
|
+
const unitPattern = Object.keys(UNITS)
|
|
51
|
+
.sort((a, b) => b.length - a.length)
|
|
52
|
+
.join('|')
|
|
53
|
+
|
|
54
|
+
const RE = new RegExp(String.raw`^(-?(?:\d+)?\.?\d+)\s*(${unitPattern})?$`, 'i')
|
|
44
55
|
|
|
45
|
-
export const ms = (val:
|
|
56
|
+
export const ms = (val: Duration): number => {
|
|
46
57
|
const str = String(val)
|
|
47
|
-
if (str.length > 100) return
|
|
58
|
+
if (str.length > 100) return Number.NaN
|
|
48
59
|
|
|
49
60
|
const match = RE.exec(str)
|
|
50
|
-
if (!match) return
|
|
61
|
+
if (!match) return Number.NaN
|
|
51
62
|
|
|
52
63
|
const n = Number.parseFloat(match[1] ?? '')
|
|
53
64
|
const type = (match[2] ?? 'ms').toLowerCase()
|
|
54
|
-
return n * (UNITS[type] ?? 0)
|
|
65
|
+
return n * (UNITS[type as Unit] ?? 0)
|
|
55
66
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import type { RedisOptions } from 'ioredis'
|
|
2
|
+
import type { Duration } from './ms'
|
|
2
3
|
|
|
3
|
-
export type
|
|
4
|
+
export type { Duration } from './ms'
|
|
4
5
|
|
|
5
6
|
export type CacheData = Record<string, unknown> | Record<string, unknown>[] | unknown[] | number | undefined
|
|
6
7
|
|
|
7
8
|
export type CacheOptions = {
|
|
8
9
|
engine: 'memory' | 'redis'
|
|
9
10
|
engineOptions?: RedisOptions
|
|
10
|
-
defaultTTL?:
|
|
11
|
+
defaultTTL?: Duration
|
|
11
12
|
debug?: boolean
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
export interface CacheEngine {
|
|
15
16
|
get: (key: string) => Promise<CacheData> | CacheData
|
|
16
|
-
set: (key: string, value: CacheData, ttl?:
|
|
17
|
+
set: (key: string, value: CacheData, ttl?: Duration) => Promise<void> | void
|
|
17
18
|
del: (key: string) => Promise<void> | void
|
|
18
19
|
clear: () => Promise<void> | void
|
|
19
20
|
close: () => Promise<void> | void
|
package/tests/ms.test.ts
CHANGED
|
@@ -1,68 +1,78 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import { ms } from '../src/ms'
|
|
3
|
+
import { ms, UNITS } from '../src/ms'
|
|
4
|
+
|
|
5
|
+
const { s, m, h, d, w, mo, y } = UNITS
|
|
4
6
|
|
|
5
7
|
describe('ms', () => {
|
|
8
|
+
it('should parse milliseconds', () => {
|
|
9
|
+
expect(ms('100ms')).toBe(100)
|
|
10
|
+
expect(ms('500 milliseconds')).toBe(500)
|
|
11
|
+
expect(ms('1 millisecond')).toBe(1)
|
|
12
|
+
expect(ms('200 msec')).toBe(200)
|
|
13
|
+
expect(ms('300 msecs')).toBe(300)
|
|
14
|
+
})
|
|
15
|
+
|
|
6
16
|
it('should parse seconds', () => {
|
|
7
|
-
expect(ms('1s')).toBe(
|
|
8
|
-
expect(ms('5 seconds')).toBe(
|
|
9
|
-
expect(ms('30 sec')).toBe(
|
|
10
|
-
expect(ms('1 second')).toBe(
|
|
11
|
-
expect(ms('2 secs')).toBe(
|
|
17
|
+
expect(ms('1s')).toBe(s)
|
|
18
|
+
expect(ms('5 seconds')).toBe(5 * s)
|
|
19
|
+
expect(ms('30 sec')).toBe(30 * s)
|
|
20
|
+
expect(ms('1 second')).toBe(s)
|
|
21
|
+
expect(ms('2 secs')).toBe(2 * s)
|
|
12
22
|
})
|
|
13
23
|
|
|
14
24
|
it('should parse minutes', () => {
|
|
15
|
-
expect(ms('1m')).toBe(
|
|
16
|
-
expect(ms('5 minutes')).toBe(
|
|
17
|
-
expect(ms('1 minute')).toBe(
|
|
18
|
-
expect(ms('2 min')).toBe(
|
|
19
|
-
expect(ms('3 mins')).toBe(
|
|
25
|
+
expect(ms('1m')).toBe(m)
|
|
26
|
+
expect(ms('5 minutes')).toBe(5 * m)
|
|
27
|
+
expect(ms('1 minute')).toBe(m)
|
|
28
|
+
expect(ms('2 min')).toBe(2 * m)
|
|
29
|
+
expect(ms('3 mins')).toBe(3 * m)
|
|
20
30
|
})
|
|
21
31
|
|
|
22
32
|
it('should parse hours', () => {
|
|
23
|
-
expect(ms('1h')).toBe(
|
|
24
|
-
expect(ms('2 hours')).toBe(
|
|
25
|
-
expect(ms('1 hour')).toBe(
|
|
26
|
-
expect(ms('3 hr')).toBe(
|
|
27
|
-
expect(ms('4 hrs')).toBe(
|
|
33
|
+
expect(ms('1h')).toBe(h)
|
|
34
|
+
expect(ms('2 hours')).toBe(2 * h)
|
|
35
|
+
expect(ms('1 hour')).toBe(h)
|
|
36
|
+
expect(ms('3 hr')).toBe(3 * h)
|
|
37
|
+
expect(ms('4 hrs')).toBe(4 * h)
|
|
28
38
|
})
|
|
29
39
|
|
|
30
40
|
it('should parse days', () => {
|
|
31
|
-
expect(ms('1d')).toBe(
|
|
32
|
-
expect(ms('2 days')).toBe(
|
|
33
|
-
expect(ms('1 day')).toBe(
|
|
41
|
+
expect(ms('1d')).toBe(d)
|
|
42
|
+
expect(ms('2 days')).toBe(2 * d)
|
|
43
|
+
expect(ms('1 day')).toBe(d)
|
|
34
44
|
})
|
|
35
45
|
|
|
36
46
|
it('should parse weeks', () => {
|
|
37
|
-
expect(ms('1w')).toBe(
|
|
38
|
-
expect(ms('2 weeks')).toBe(
|
|
39
|
-
expect(ms('1 week')).toBe(
|
|
47
|
+
expect(ms('1w')).toBe(w)
|
|
48
|
+
expect(ms('2 weeks')).toBe(2 * w)
|
|
49
|
+
expect(ms('1 week')).toBe(w)
|
|
40
50
|
})
|
|
41
51
|
|
|
42
|
-
it('should parse
|
|
43
|
-
expect(ms('
|
|
44
|
-
expect(ms('1
|
|
45
|
-
expect(ms('2
|
|
46
|
-
expect(ms('
|
|
52
|
+
it('should parse months', () => {
|
|
53
|
+
expect(ms('1mo')).toBe(mo)
|
|
54
|
+
expect(ms('1 month')).toBe(mo)
|
|
55
|
+
expect(ms('2 months')).toBe(2 * mo)
|
|
56
|
+
expect(ms('6mo')).toBe(6 * mo)
|
|
57
|
+
expect(ms('0.5mo')).toBe(0.5 * mo)
|
|
47
58
|
})
|
|
48
59
|
|
|
49
|
-
it('should parse
|
|
50
|
-
expect(ms('
|
|
51
|
-
expect(ms('
|
|
52
|
-
expect(ms('
|
|
53
|
-
expect(ms('
|
|
54
|
-
expect(ms('300 msecs')).toBe(300)
|
|
60
|
+
it('should parse years', () => {
|
|
61
|
+
expect(ms('1y')).toBe(y)
|
|
62
|
+
expect(ms('1 year')).toBe(y)
|
|
63
|
+
expect(ms('2 yrs')).toBe(2 * y)
|
|
64
|
+
expect(ms('1 yr')).toBe(y)
|
|
55
65
|
})
|
|
56
66
|
|
|
57
67
|
it('should parse decimal values', () => {
|
|
58
|
-
expect(ms('1.5h')).toBe(
|
|
59
|
-
expect(ms('0.5d')).toBe(
|
|
60
|
-
expect(ms('.5s')).toBe(
|
|
68
|
+
expect(ms('1.5h')).toBe(1.5 * h)
|
|
69
|
+
expect(ms('0.5d')).toBe(0.5 * d)
|
|
70
|
+
expect(ms('.5s')).toBe(0.5 * s)
|
|
61
71
|
})
|
|
62
72
|
|
|
63
73
|
it('should parse negative values', () => {
|
|
64
|
-
expect(ms('-1s')).toBe(-
|
|
65
|
-
expect(ms('-3m')).toBe(-
|
|
74
|
+
expect(ms('-1s')).toBe(-s)
|
|
75
|
+
expect(ms('-3m')).toBe(-3 * m)
|
|
66
76
|
})
|
|
67
77
|
|
|
68
78
|
it('should default to milliseconds without unit', () => {
|
|
@@ -71,23 +81,33 @@ describe('ms', () => {
|
|
|
71
81
|
})
|
|
72
82
|
|
|
73
83
|
it('should be case insensitive', () => {
|
|
74
|
-
expect
|
|
75
|
-
expect(ms('
|
|
76
|
-
expect
|
|
84
|
+
// @ts-expect-error runtime check
|
|
85
|
+
expect(ms('1S')).toBe(s)
|
|
86
|
+
// @ts-expect-error runtime check
|
|
87
|
+
expect(ms('1M')).toBe(m)
|
|
88
|
+
// @ts-expect-error runtime check
|
|
89
|
+
expect(ms('1H')).toBe(h)
|
|
77
90
|
})
|
|
78
91
|
|
|
79
|
-
it('should return
|
|
80
|
-
expect
|
|
81
|
-
expect(ms('')).
|
|
82
|
-
expect
|
|
92
|
+
it('should return NaN for invalid strings', () => {
|
|
93
|
+
// @ts-expect-error testing invalid input
|
|
94
|
+
expect(ms('invalid')).toBeNaN()
|
|
95
|
+
// @ts-expect-error testing invalid input
|
|
96
|
+
expect(ms('')).toBeNaN()
|
|
97
|
+
// @ts-expect-error testing invalid input
|
|
98
|
+
expect(ms('abc123')).toBeNaN()
|
|
83
99
|
})
|
|
84
100
|
|
|
85
|
-
it('should return
|
|
86
|
-
expect
|
|
101
|
+
it('should return NaN for strings longer than 100 characters', () => {
|
|
102
|
+
// @ts-expect-error testing invalid input
|
|
103
|
+
expect(ms('a'.repeat(101))).toBeNaN()
|
|
87
104
|
})
|
|
88
105
|
|
|
89
106
|
it('should handle whitespace between number and unit', () => {
|
|
90
|
-
expect(ms('1 s')).toBe(
|
|
91
|
-
expect(ms('5 minutes')).toBe(
|
|
107
|
+
expect(ms('1 s')).toBe(s)
|
|
108
|
+
expect(ms('5 minutes')).toBe(5 * m)
|
|
109
|
+
expect(ms('1 mo')).toBe(mo)
|
|
110
|
+
expect(ms('1 week')).toBe(w)
|
|
111
|
+
expect(ms('1 year')).toBe(y)
|
|
92
112
|
})
|
|
93
113
|
})
|
package/tsconfig.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"include": ["src"],
|
|
3
3
|
"compilerOptions": {
|
|
4
|
-
"target": "
|
|
5
|
-
"lib": ["
|
|
4
|
+
"target": "ES2022",
|
|
5
|
+
"lib": ["ES2022"],
|
|
6
6
|
"types": ["node"],
|
|
7
7
|
"module": "Preserve",
|
|
8
8
|
"moduleResolution": "bundler",
|
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
"experimentalDecorators": true,
|
|
19
19
|
"exactOptionalPropertyTypes": true,
|
|
20
20
|
"forceConsistentCasingInFileNames": true,
|
|
21
|
-
"importHelpers": true,
|
|
22
21
|
"isolatedModules": true,
|
|
23
22
|
"noEmitOnError": true,
|
|
24
23
|
"noFallthroughCasesInSwitch": true,
|