Skip to content

Commit a14fb4a

Browse files
author
Spencer
authored
[6.5] [@kbn/datemath] improve types (#24671) (#24802)
Backports the following commits to 6.5: - [@kbn/datemath] improve types (#24671)
1 parent d56cf2a commit a14fb4a

7 files changed

Lines changed: 58 additions & 26 deletions

File tree

packages/kbn-datemath/src/index.d.ts

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,29 @@
1717
* under the License.
1818
*/
1919

20-
declare module '@kbn/datemath' {
21-
const dateMath: {
22-
parse: any;
23-
unitsMap: any;
24-
units: string[];
25-
unitsAsc: string[];
26-
unitsDesc: string[];
20+
import moment from 'moment';
21+
export type Unit = 'ms' | 's' | 'm' | 'h' | 'd' | 'w' | 'M' | 'y';
22+
23+
declare const datemath: {
24+
unitsMap: {
25+
[k in Unit]: {
26+
weight: number;
27+
type: 'calendar' | 'fixed' | 'mixed';
28+
base: number;
29+
}
2730
};
28-
export default dateMath;
29-
}
31+
units: Unit[];
32+
unitsAsc: Unit[];
33+
unitsDesc: Unit[];
34+
35+
parse(
36+
input: string,
37+
options?: {
38+
roundUp?: boolean;
39+
forceNow?: boolean;
40+
momentInstance?: typeof moment;
41+
}
42+
): moment.Moment | undefined;
43+
};
44+
45+
export default datemath;

packages/kbn-datemath/src/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ const unitsMap = {
2525
m: { weight: 3, type: 'mixed', base: 1000 * 60 },
2626
h: { weight: 4, type: 'mixed', base: 1000 * 60 * 60 },
2727
d: { weight: 5, type: 'mixed', base: 1000 * 60 * 60 * 24 },
28-
w: { weight: 6, type: 'calendar' },
29-
M: { weight: 7, type: 'calendar' },
28+
w: { weight: 6, type: 'calendar', base: NaN },
29+
M: { weight: 7, type: 'calendar', base: NaN },
3030
// q: { weight: 8, type: 'calendar' }, // TODO: moment duration does not support quarter
31-
y: { weight: 9, type: 'calendar' },
31+
y: { weight: 9, type: 'calendar', base: NaN },
3232
};
3333
const units = Object.keys(unitsMap).sort((a, b) => unitsMap[b].weight - unitsMap[a].weight);
3434
const unitsDesc = [...units];

src/ui/public/utils/parse_es_interval/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@
1717
* under the License.
1818
*/
1919

20-
export { parseEsInterval } from './parse_es_interval';
20+
export { parseEsInterval, ParsedInterval } from './parse_es_interval';
2121
export { InvalidEsCalendarIntervalError } from './invalid_es_calendar_interval_error';
2222
export { InvalidEsIntervalFormatError } from './invalid_es_interval_format_error';

src/ui/public/utils/parse_es_interval/invalid_es_calendar_interval_error.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717
* under the License.
1818
*/
1919

20+
import { Unit } from '@kbn/datemath';
21+
2022
export class InvalidEsCalendarIntervalError extends Error {
2123
constructor(
2224
public readonly interval: string,
2325
public readonly value: number,
24-
public readonly unit: string,
26+
public readonly unit: Unit,
2527
public readonly type: string
2628
) {
2729
super(`Invalid calendar interval: ${interval}, value must be 1`);

src/ui/public/utils/parse_es_interval/parse_es_interval.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* under the License.
1818
*/
1919

20-
import dateMath from '@kbn/datemath';
20+
import dateMath, { Unit } from '@kbn/datemath';
2121

2222
import { InvalidEsCalendarIntervalError } from './invalid_es_calendar_interval_error';
2323
import { InvalidEsIntervalFormatError } from './invalid_es_interval_format_error';
@@ -26,6 +26,8 @@ const ES_INTERVAL_STRING_REGEX = new RegExp(
2626
'^([1-9][0-9]*)\\s*(' + dateMath.units.join('|') + ')$'
2727
);
2828

29+
export type ParsedInterval = ReturnType<typeof parseEsInterval>;
30+
2931
/**
3032
* Extracts interval properties from an ES interval string. Disallows unrecognized interval formats
3133
* and fractional values. Converts some intervals from "calendar" to "fixed" when the number of
@@ -37,15 +39,15 @@ const ES_INTERVAL_STRING_REGEX = new RegExp(
3739
* | -------- | ---------------- | ------------------- |
3840
* | ms | fixed | fixed |
3941
* | s | fixed | fixed |
40-
* | m | fixed | fixed |
42+
* | m | calendar | fixed |
4143
* | h | calendar | fixed |
4244
* | d | calendar | fixed |
4345
* | w | calendar | N/A - disallowed |
4446
* | M | calendar | N/A - disallowed |
4547
* | y | calendar | N/A - disallowed |
4648
*
4749
*/
48-
export function parseEsInterval(interval: string): { value: number; unit: string; type: string } {
50+
export function parseEsInterval(interval: string) {
4951
const matches = String(interval)
5052
.trim()
5153
.match(ES_INTERVAL_STRING_REGEX);
@@ -54,9 +56,9 @@ export function parseEsInterval(interval: string): { value: number; unit: string
5456
throw new InvalidEsIntervalFormatError(interval);
5557
}
5658

57-
const value = matches && parseFloat(matches[1]);
58-
const unit = matches && matches[2];
59-
const type = unit && dateMath.unitsMap[unit].type;
59+
const value = parseFloat(matches[1]);
60+
const unit = matches[2] as Unit;
61+
const type = dateMath.unitsMap[unit].type;
6062

6163
if (type === 'calendar' && value !== 1) {
6264
throw new InvalidEsCalendarIntervalError(interval, value, unit, type);
@@ -65,6 +67,9 @@ export function parseEsInterval(interval: string): { value: number; unit: string
6567
return {
6668
value,
6769
unit,
68-
type: (type === 'mixed' && value === 1) || type === 'calendar' ? 'calendar' : 'fixed',
70+
type:
71+
(type === 'mixed' && value === 1) || type === 'calendar'
72+
? ('calendar' as 'calendar')
73+
: ('fixed' as 'fixed'),
6974
};
7075
}

src/ui/public/vis/lib/least_common_interval.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ describe('leastCommonInterval', () => {
4848
expect(() => {
4949
leastCommonInterval('60 s', '1m');
5050
}).toThrowError();
51+
expect(() => {
52+
leastCommonInterval('1m', '2m');
53+
}).toThrowError();
54+
expect(() => {
55+
leastCommonInterval('1h', '2h');
56+
}).toThrowError();
5157
expect(() => {
5258
leastCommonInterval('1d', '7d');
5359
}).toThrowError();

src/ui/public/vis/lib/least_common_interval.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ import { parseEsInterval } from '../../utils/parse_es_interval';
2525
* Finds the lowest common interval between two given ES date histogram intervals
2626
* in the format of (value)(unit)
2727
*
28-
* - `ms, s` units are fixed-length intervals
29-
* - `m, h, d` units are fixed-length intervals when value > 1 (i.e. 2m, 24h, 7d),
28+
* - `ms` units are fixed-length intervals
29+
* - `s, m, h, d` units are fixed-length intervals when value > 1 (i.e. 2m, 24h, 7d),
3030
* but calendar interval when value === 1
3131
* - `w, M, q, y` units are calendar intervals and do not support multiple, aka
3232
* value must === 1
@@ -51,7 +51,7 @@ export function leastCommonInterval(a: string, b: string): string {
5151
}
5252

5353
// If intervals are calendar units, pick the larger one (calendar value is always 1)
54-
if (aInt.type === 'calendar') {
54+
if (aInt.type === 'calendar' || bInt.type === 'calendar') {
5555
return aUnit.weight > bUnit.weight ? `${aInt.value}${aInt.unit}` : `${bInt.value}${bInt.unit}`;
5656
}
5757

@@ -68,8 +68,11 @@ export function leastCommonInterval(a: string, b: string): string {
6868
return a.replace(/\s/g, '');
6969
}
7070

71-
// Otherwise find the biggest unit that divides evenly
72-
const lcmUnit = unitsDesc.find(unit => unitsMap[unit].base && lcmMs % unitsMap[unit].base === 0);
71+
// Otherwise find the biggest non-calendar unit that divides evenly
72+
const lcmUnit = unitsDesc.find(unit => {
73+
const unitInfo = unitsMap[unit];
74+
return !!(unitInfo.type !== 'calendar' && lcmMs % unitInfo.base === 0);
75+
});
7376

7477
// Throw error in case we couldn't divide evenly, theoretically we never get here as everything is
7578
// divisible by 1 millisecond

0 commit comments

Comments
 (0)