1 | # destr
|
2 |
|
3 | [![npm version][npm-version-src]][npm-version-href]
|
4 | [![npm downloads][npm-downloads-src]][npm-downloads-href]
|
5 | [![bundle][bundle-src]][bundle-href]
|
6 | [![License][license-src]][license-href]
|
7 |
|
8 | A faster, secure and convenient alternative for [`JSON.parse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse).
|
9 |
|
10 | ## Usage
|
11 |
|
12 | ### Node.js
|
13 |
|
14 | Install dependency:
|
15 |
|
16 | ```bash
|
17 | # npm
|
18 | npm i destr
|
19 |
|
20 | # yarn
|
21 | yarn add destr
|
22 |
|
23 | # pnpm
|
24 | pnpm i destr
|
25 | ```
|
26 |
|
27 | Import into your Node.js project:
|
28 |
|
29 | ```js
|
30 | // ESM
|
31 | import { destr, safeDestr } from "destr";
|
32 |
|
33 | // CommonJS
|
34 | const { destr, safeDestr } = require("destr");
|
35 | ```
|
36 |
|
37 | ### Deno
|
38 |
|
39 | ```js
|
40 | import { destr, safeDestr } from "https://deno.land/x/destr/src/index.ts";
|
41 |
|
42 | console.log(destr('{ "deno": "yay" }'));
|
43 | ```
|
44 |
|
45 | ## Why?
|
46 |
|
47 | ### ✅ Type Safe
|
48 |
|
49 | ```ts
|
50 | const obj = JSON.parse("{}"); // obj type is any
|
51 |
|
52 | const obj = destr("{}"); // obj type is unknown by default
|
53 |
|
54 | const obj = destr<MyInterface>("{}"); // obj is well-typed
|
55 | ```
|
56 |
|
57 | ### ✅ Fast fallback to input if is not string
|
58 |
|
59 | > 🚀 Up to 500 times faster than `JSON.parse`!
|
60 |
|
61 | ```js
|
62 | // Uncaught SyntaxError: Unexpected token u in JSON at position 0
|
63 | JSON.parse();
|
64 |
|
65 | // undefined
|
66 | destr();
|
67 | ```
|
68 |
|
69 | ### ✅ Fast lookup for known string values
|
70 |
|
71 | > 🚀 Up to 900 times faster than `JSON.parse`!
|
72 |
|
73 | ```js
|
74 | // Uncaught SyntaxError: Unexpected token T in JSON at position 0
|
75 | JSON.parse("TRUE");
|
76 |
|
77 | // true
|
78 | destr("TRUE");
|
79 | ```
|
80 |
|
81 | ### ✅ Fallback to original value if parse fails (empty or any plain string)
|
82 |
|
83 | > 🚀 Up to 900 times faster than `JSON.parse`!
|
84 |
|
85 | ```js
|
86 | // Uncaught SyntaxError: Unexpected token s in JSON at position 0
|
87 | JSON.parse("salam");
|
88 |
|
89 | // "salam"
|
90 | destr("salam");
|
91 | ```
|
92 |
|
93 | **Note:** This fails in safe/strict mode with `safeDestr`.
|
94 |
|
95 | ### ✅ Avoid prototype pollution
|
96 |
|
97 | ```js
|
98 | const input = '{ "user": { "__proto__": { "isAdmin": true } } }';
|
99 |
|
100 | // { user: { __proto__: { isAdmin: true } } }
|
101 | JSON.parse(input);
|
102 |
|
103 | // { user: {} }
|
104 | destr(input);
|
105 | ```
|
106 |
|
107 | ### ✅ Strict Mode
|
108 |
|
109 | When using `safeDestr` it will throw an error if the input is not a valid JSON string or parsing fails. (non string values and built-ins will be still returned as-is)
|
110 |
|
111 | ```js
|
112 | // Returns "[foo"
|
113 | destr("[foo");
|
114 |
|
115 | // Throws an error
|
116 | safeDestr("[foo");
|
117 | ```
|
118 |
|
119 | ## Benchmarks
|
120 |
|
121 | `destr` is sometimes little bit slower than `JSON.parse` when parsing a valid JSON string mainly because of transform to avoid [prototype pollution](https://learn.snyk.io/lessons/prototype-pollution/javascript/) which can lead to serious security issues if not being sanitized. In the other words, `destr` is better when input is not always a JSON string or from untrusted source like request body.
|
122 |
|
123 | Check [Benchmarks](./BENCH.md)
|
124 |
|
125 | ## License
|
126 |
|
127 | MIT. Made with 💖
|
128 |
|
129 |
|
130 |
|
131 | [npm-version-src]: https://img.shields.io/npm/v/destr?style=flat&colorA=18181B&colorB=F0DB4F
|
132 | [npm-version-href]: https://npmjs.com/package/destr
|
133 | [npm-downloads-src]: https://img.shields.io/npm/dm/destr?style=flat&colorA=18181B&colorB=F0DB4F
|
134 | [npm-downloads-href]: https://npmjs.com/package/destr
|
135 | [bundle-src]: https://img.shields.io/bundlephobia/minzip/destr?style=flat&colorA=18181B&colorB=F0DB4F
|
136 | [bundle-href]: https://bundlephobia.com/result?p=destr
|
137 | [license-src]: https://img.shields.io/github/license/unjs/destr.svg?style=flat&colorA=18181B&colorB=F0DB4F
|
138 | [license-href]: https://github.com/unjs/destr/blob/main/LICENSE
|