1 | # 🤔 JSON Infer Types
|
2 |
|
3 | > Infer the types of JSON documents & values, with a large set of formats for strings
|
4 |
|
5 | ![Coverage lines](./badges/badge-lines.svg)
|
6 | ![Tests](https://github.com/jsonhero-io/json-infer-types/actions/workflows/test.yml/badge.svg?branch=main)
|
7 | [![Downloads](https://img.shields.io/npm/dm/%40jsonhero%2Fjson-infer-types.svg)](https://npmjs.com/@jsonhero/json-infer-types)
|
8 | [![Install size](https://packagephobia.com/badge?p=%40jsonhero%2Fjson-infer-types)](https://packagephobia.com/result?p=@jsonhero/json-infer-types)
|
9 |
|
10 | - [🚀 Features](#-features)
|
11 | - [💻 Usage](#-usage)
|
12 | - [Strings](#strings)
|
13 | - [String Formats](#string-formats)
|
14 | - [Date/Time strings](#datetime-strings)
|
15 | - [URI strings](#uri-strings)
|
16 | - [Email address strings](#email-address-strings)
|
17 | - [Other formats](#other-formats)
|
18 | - [Roadmap](#roadmap)
|
19 |
|
20 | ## 🚀 Features
|
21 |
|
22 | - Written in typescript
|
23 | - Narrows type of the value when using with Typescript
|
24 | - Lightweight with only a few third-party dependencies
|
25 | - Includes a large set of formats for strings
|
26 | - Dates and times (and timestamps)
|
27 | - URIs
|
28 | - Email addresses
|
29 | - Currencies
|
30 | - Countries
|
31 | - Top-Level Domains
|
32 | - IP Addresses
|
33 | - Languages
|
34 | - Phone Numbers
|
35 | - UUIDs
|
36 | - Hostnames
|
37 | - File sizes
|
38 | - Stringified JSON
|
39 |
|
40 | ## 💻 Usage
|
41 |
|
42 | Install JSON Infer Types
|
43 |
|
44 | ```bash
|
45 | $ npm install --save @jsonhero/json-infer-types
|
46 | ```
|
47 |
|
48 | `inferType` takes any JSON value and returns a `JSONValueType` object:
|
49 |
|
50 | ```js
|
51 | const { inferType } = require("@jsonhero/json-infer-types");
|
52 |
|
53 | inferType(123); // => { name: "int", value: 123 }
|
54 | ```
|
55 |
|
56 | The following types are supported:
|
57 |
|
58 | ```js
|
59 | inferType(null); // => { name: "null", value: null }
|
60 | inferType(undefined); // => { name: "null", value: null }
|
61 | inferType(true); // => { name: "bool", value: true }
|
62 | inferType(123); // => { name: "int", value: 123 }
|
63 | inferType(123.456); // => { name: "float", value: 123.456 }
|
64 | inferType("hello world"); // => { name: "string", value: "hello world" }
|
65 | inferType({ foo: "bar" }); // => { name: "object", value: { foo: "bar" } }
|
66 | inferType([1, 2, 3]); // => { name: "array", value: [1, 2, 3] }
|
67 | ```
|
68 |
|
69 | ### Strings
|
70 |
|
71 | JSON Infer Types will also recognize certain string formats and include that information in the result, for example if the string is a `URI`:
|
72 |
|
73 | ```js
|
74 | inferType("https://www.example.com/foo#bar");
|
75 | ```
|
76 |
|
77 | Will be
|
78 |
|
79 | ```json
|
80 | {
|
81 | "name": "string",
|
82 | "value": "https://www.example.com/foo#bar",
|
83 | "format": {
|
84 | "name": "uri"
|
85 | }
|
86 | }
|
87 | ```
|
88 |
|
89 | Some formats have mutliple variants, like IP Address. `inferType("192.168.0.1")` will be interpreted as an IPV4 address
|
90 |
|
91 | ```json
|
92 | {
|
93 | "name": "string",
|
94 | "value": "192.168.0.1",
|
95 | "format": {
|
96 | "name": "ip",
|
97 | "variant": "v4"
|
98 | }
|
99 | }
|
100 | ```
|
101 |
|
102 | And `inferType("2001:db8:1234::1")` will be interpreted as an IPV6 address
|
103 |
|
104 | ```json
|
105 | {
|
106 | "name": "string",
|
107 | "value": "2001:db8:1234::1",
|
108 | "format": {
|
109 | "name": "ip",
|
110 | "variant": "v6"
|
111 | }
|
112 | }
|
113 | ```
|
114 |
|
115 | ## String Formats
|
116 |
|
117 | ### Date/Time strings
|
118 |
|
119 | JSON Infer Types supports `rfc3339/iso8601` and `rfc2822` string formats
|
120 |
|
121 | ```js
|
122 | inferType("2019-01-01 00:00:00.000Z");
|
123 | ```
|
124 |
|
125 | Will result in
|
126 |
|
127 | ```json
|
128 | {
|
129 | "name": "string",
|
130 | "value": "2019-01-01 00:00:00.000Z",
|
131 | "format": {
|
132 | "name": "datetime",
|
133 | "parts": "datetime",
|
134 | "variant": "rfc3339"
|
135 | }
|
136 | }
|
137 | ```
|
138 |
|
139 | The `parts` field can be either `datetime`, `date` or `time`, depending on the contents of the string.
|
140 |
|
141 | The following table illustrates the results of different Date/Time strings
|
142 |
|
143 | | String | Variant | Parts |
|
144 | | ----------------------------------- | ------- | -------- |
|
145 | | `"2019-01-01 00:00:00.000Z"` | rfc3339 | datetime |
|
146 | | `"2019-10-12T14:20:50.52+07:00"` | rfc3339 | datetime |
|
147 | | `"1983-10-14T13:30Z"` | rfc3339 | datetime |
|
148 | | `"2016-05-25"` | rfc3339 | date |
|
149 | | `"+002016-05-25"` | rfc3339 | date |
|
150 | | `"2016-W21-3"` | rfc3339 | date |
|
151 | | `"09:24:15.123Z"` | rfc3339 | time |
|
152 | | `"09:24:15.123Z"` | rfc3339 | time |
|
153 | | `"09:24:15"` | rfc3339 | time |
|
154 | | `"Mon, 02 Jan 2017 06:00:00 -0800"` | rfc2822 | datetime |
|
155 | | `"Mon, 02 Jan 2017 06:00:00 PST"` | rfc2822 | datetime |
|
156 |
|
157 | JSON Infer Types also supports unix epoch timestamps
|
158 |
|
159 | ```js
|
160 | inferType("1596597629980");
|
161 | ```
|
162 |
|
163 | Will result in
|
164 |
|
165 | ```json
|
166 | {
|
167 | "name": "string",
|
168 | "value": "1596597629980",
|
169 | "format": {
|
170 | "name": "timestamp",
|
171 | "variant": "millisecondsSinceEpoch"
|
172 | }
|
173 | }
|
174 | ```
|
175 |
|
176 | Also supported are seconds and nanoseconds since epoch timestamp strings
|
177 |
|
178 | ### URI strings
|
179 |
|
180 | JSON Infer Types will interpret certain strings to be URIs
|
181 |
|
182 | ```js
|
183 | inferType("https://www.example.com/foo#bar");
|
184 | ```
|
185 |
|
186 | Will result in
|
187 |
|
188 | ```json
|
189 | {
|
190 | "name": "string",
|
191 | "value": "https://www.example.com/foo#bar",
|
192 | "format": {
|
193 | "name": "uri"
|
194 | }
|
195 | }
|
196 | ```
|
197 |
|
198 | If the URI contains a file extension, the inferred `contentType` will be included in the result. For example `inferType("https://www.example.com/foo.json")` will result in
|
199 |
|
200 | ```json
|
201 | {
|
202 | "name": "string",
|
203 | "value": "https://www.example.com/foo.json",
|
204 | "format": {
|
205 | "name": "uri",
|
206 | "contentType": "application/json"
|
207 | }
|
208 | }
|
209 | ```
|
210 |
|
211 | The mapping of file extension to contentType is done using the [mime-types](https://github.com/jshttp/mime-types) package
|
212 |
|
213 | ### Email address strings
|
214 |
|
215 | JSON Infer Types supports `rfc5321` and `rfc5321` style email address strings:
|
216 |
|
217 | ```js
|
218 | inferType("eallam@example.com");
|
219 | ```
|
220 |
|
221 | Will result in
|
222 |
|
223 | ```json
|
224 | {
|
225 | "name": "string",
|
226 | "value": "eallam@example.com",
|
227 | "format": {
|
228 | "name": "email",
|
229 | "variant": "rfc5321"
|
230 | }
|
231 | }
|
232 | ```
|
233 |
|
234 | The following table illustrates the results of different email strings
|
235 |
|
236 | | String | Variant |
|
237 | | ------------------------------------------------ | ------- |
|
238 | | `"example+suffix@example.com"` | rfc5321 |
|
239 | | `"example@127.0.0.1"` | rfc5321 |
|
240 | | `"foo@example.accountants"` | rfc5321 |
|
241 | | `"Example Name <example@example.com>"` | rfc5322 |
|
242 | | `"Example S. Name <example.s.name@example.com>"` | rfc5322 |
|
243 |
|
244 | ### Other formats
|
245 |
|
246 | The following table illustrates the rest of the formats JSON Infer Types supports
|
247 |
|
248 | | Example Strings | Name | Variant |
|
249 | | ----------------------------------------- | ----------- | --------- |
|
250 | | `"USD"`, `"BTC"` | currency | iso4217 |
|
251 | | `"United States dollar"`, `"Euro"` | currency | english |
|
252 | | `"ETH"`, `"LTC"` | currency | crypto |
|
253 | | `"USA"`, `"MMR"` | country | iso3166-3 |
|
254 | | `"US"`, `"GB"`, `"JP"` | country | iso3166-2 |
|
255 | | `".com"`, `".co.uk"`, `".biz"` | tld | |
|
256 | | `"192.168.0.1"`, `"172.16.0.0"`, `".biz"` | ip | v4 |
|
257 | | `"2001:db8:1234::1"` | ip | v6 |
|
258 | | `"en"`, `"ab"`, `"es"` | language | iso693-1 |
|
259 | | `"eng"`, `"eus"`, `"zul"` | language | iso693-2 |
|
260 | | `"Arabic"`, `"Welsh"`, `"Russian"` | language | english |
|
261 | | `"dansk"`, `"Español"` | language | native |
|
262 | | `"+1 (684) 633-5115"`, `"+49 30 83050"` | phoneNumber | e.164 |
|
263 | | `"4677658f-8865-47db-afb0-908e25246348"` | uuid | v4 |
|
264 | | `"cfa649f0-650b-11ec-acb3-03462fc79f5d"` | uuid | v1 |
|
265 | | `"bde4a7b9-5793-5a1f-b378-211205b15898"` | uuid | v5 |
|
266 | | `"foo.example.com"`, `"localhost"` | hostname | rfc1123 |
|
267 | | `"exa_mple.com"` | hostname | rfc5890 |
|
268 | | `"544B"`, `"1.0MB"`, `"377K"`, `"1.87GB"` | filesize | human |
|
269 | | `'{ "foo": 1 }'` | json | ecma262 |
|
270 | | `'{ foo: 1, }'` | json | json5 |
|
271 |
|
272 | Please feel free to request additional formats by opening a [Github issue](https://github.com/jsonhero-io/json-infer-types/issues)
|
273 |
|
274 | ## Roadmap
|
275 |
|
276 | - Infer Firestore timestamps
|
277 | - Infer semver string
|
278 | - Infer Emoji
|