Skip to content

Commit 2c90eb8

Browse files
author
David Haven
authored
Infer int timestamps (#18)
* infer timestamps from int + test file * fix typo * replace string typecast with recursive call
1 parent 74b159b commit 2c90eb8

File tree

6 files changed

+81
-6
lines changed

6 files changed

+81
-6
lines changed

src/@types.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { JSONStringFormat, JSONObjectFormat } from "./formats";
1+
import { JSONStringFormat, JSONObjectFormat, JSONIntFormat } from "./formats";
22

33
export type JSONNullType = {
44
name: "null";
@@ -17,6 +17,7 @@ export type JSONFloatType = {
1717

1818
export type JSONIntType = {
1919
name: "int";
20+
format?: JSONIntFormat;
2021
value: number;
2122
};
2223

src/formats/index.ts

+16
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,19 @@ export function inferObjectFormat(value: object): JSONObjectFormat | undefined {
119119

120120
return undefined;
121121
}
122+
123+
export type JSONIntFormat = JSONTimestampFormat
124+
125+
const intFormats = [inferTimestamp];
126+
127+
export function inferIntFormat(value: number): JSONIntFormat | undefined {
128+
for (const [, format] of Object.entries(intFormats)) {
129+
const result = format(value);
130+
131+
if (result) {
132+
return result;
133+
}
134+
}
135+
136+
return undefined;
137+
}

src/formats/timestamp.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ function inRangeOfNow(msSinceEpoch: number): boolean {
1818
return now >= lowerBound && now <= upperBound;
1919
}
2020

21-
export function inferTimestamp(value: string): JSONTimestampFormat | undefined {
21+
export function inferTimestamp(value: string | number): JSONTimestampFormat | undefined {
22+
if (typeof value === "number") {
23+
return inferTimestamp(`${value}`);
24+
}
2225
if (timestampSecondsSinceEpoch.test(value)) {
2326
const seconds = parseInt(value);
2427

src/index.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { JSONValueType } from "./@types";
2-
import { inferFormat, inferObjectFormat } from "./formats";
2+
import { inferFormat, inferObjectFormat, inferIntFormat } from "./formats";
33

44
export { JSONValueType };
55
export {
@@ -45,7 +45,11 @@ export function inferType(value: unknown): JSONValueType {
4545

4646
if (typeof value === "number") {
4747
if (Number.isInteger(value)) {
48-
return { name: "int", value };
48+
return {
49+
name: "int",
50+
value,
51+
format: inferIntFormat(value),
52+
};
4953
} else {
5054
return { name: "float", value };
5155
}

tests/intFormats.test.ts

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { inferType } from "../src";
2+
3+
describe("timestamps", () => {
4+
test.each([1664976736123, 1664976736567])(
5+
"%p should be inferred as an timestamp",
6+
(value) => {
7+
expect(inferType(value)).toEqual({
8+
name: "int",
9+
value,
10+
format: {
11+
name: "timestamp",
12+
variant: "millisecondsSinceEpoch",
13+
},
14+
});
15+
},
16+
);
17+
18+
test.each([1664976736, 1664976736])("%p should be inferred as an timestamp", (value) => {
19+
expect(inferType(value)).toEqual({
20+
name: "int",
21+
value,
22+
format: {
23+
name: "timestamp",
24+
variant: "secondsSinceEpoch",
25+
},
26+
});
27+
});
28+
29+
test.each([1664976736946364285])("%p should be inferred as an timestamp", (value) => {
30+
expect(inferType(value)).toEqual({
31+
name: "int",
32+
value,
33+
format: {
34+
name: "timestamp",
35+
variant: "nanosecondsSinceEpoch",
36+
},
37+
});
38+
});
39+
});
40+
41+
describe("without format", () => {
42+
test.each([46, 2244994945, 1212092628029698048])(
43+
"%p should be inferred as having no format",
44+
(value) => {
45+
expect(inferType(value)).toEqual({
46+
name: "int",
47+
value,
48+
});
49+
},
50+
);
51+
});

tests/stringFormats.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ describe("rfc2822", () => {
162162
});
163163

164164
describe("timestamps", () => {
165-
test.each(["1596597629980", "1640273437757"])(
165+
test.each(["1664976736980", "1640273437757"])(
166166
"%p should be inferred as an timestamp",
167167
(value) => {
168168
expect(inferType(value)).toEqual({
@@ -187,7 +187,7 @@ describe("timestamps", () => {
187187
});
188188
});
189189

190-
test.each(["1596597839946364285"])("%p should be inferred as an timestamp", (value) => {
190+
test.each(["1664976736946364285"])("%p should be inferred as an timestamp", (value) => {
191191
expect(inferType(value)).toEqual({
192192
name: "string",
193193
value,

0 commit comments

Comments
 (0)