Comparing version 1.1.1 to 1.2.0
@@ -1,3 +0,6 @@ | ||
declare function destr(val: any): any; | ||
declare type Options = { | ||
strict?: boolean; | ||
}; | ||
declare function destr(val: any, options?: Options): any; | ||
export { destr as default }; | ||
export { Options, destr as default }; |
{ | ||
"name": "destr", | ||
"version": "1.1.1", | ||
"version": "1.2.0", | ||
"description": "A faster, secure and convenient alternative for JSON.parse", | ||
"repository": "unjs/destr", | ||
"license": "MIT", | ||
"main": "./dist/index.cjs", | ||
"module": "./dist/index.mjs", | ||
"type": "module", | ||
"exports": { | ||
".": { | ||
"types": "./dist/index.d.ts", | ||
"import": "./dist/index.mjs", | ||
@@ -16,3 +15,5 @@ "require": "./dist/index.cjs" | ||
}, | ||
"types": "dist/index.d.ts", | ||
"main": "./dist/index.cjs", | ||
"module": "./dist/index.mjs", | ||
"types": "./dist/index.d.ts", | ||
"files": [ | ||
@@ -22,13 +23,12 @@ "dist" | ||
"devDependencies": { | ||
"@hapi/bourne": "latest", | ||
"@nuxtjs/eslint-config-typescript": "latest", | ||
"benchmark": "latest", | ||
"eslint": "latest", | ||
"rollup-plugin-typescript2": "latest", | ||
"secure-json-parse": "latest", | ||
"standard-version": "latest", | ||
"typescript": "latest", | ||
"unbuild": "latest" | ||
"@hapi/bourne": "^3.0.0", | ||
"@nuxtjs/eslint-config-typescript": "^11.0.0", | ||
"benchmark": "^2.1.4", | ||
"eslint": "^8.25.0", | ||
"secure-json-parse": "^2.5.0", | ||
"standard-version": "^9.5.0", | ||
"typescript": "^4.8.4", | ||
"unbuild": "^0.9.4" | ||
}, | ||
"packageManager": "pnpm@6.32.3", | ||
"packageManager": "pnpm@6.34.0", | ||
"scripts": { | ||
@@ -41,3 +41,3 @@ "bench": "pnpm build && node ./bench.cjs", | ||
}, | ||
"readme": "# destr\n\n> A faster, secure and convenient alternative for [`JSON.parse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse):\n\n[![npm version][npm-v-src]][npm-v-href]\n[![npm downloads][npm-d-src]][npm-d-href]\n[![bundle phobia][bundlephobia-src]][bundlephobia-href]\n\n## Usage\n\n### Node.js\n\nInstall using npm or yarn:\n\n```bash\nnpm i destr\n# or\nyarn add destr\n```\n\nImport into your Node.js project:\n\n```js\n// CommonJS\nconst destr = require('destr')\n\n// ESM\nimport destr from 'destr'\n```\n\n### Deno\n\n```js\nimport destr from 'https://deno.land/x/destr/src/index.ts'\n\nconsole.log(destr('{ \"deno\": \"yay\" }'))\n```\n\n## Why?\n\nPlease note that `destr` is little bit slower when parsing a standard JSON string mainly because of transform to avoid [prototype pollution](https://hueniverse.com/a-tale-of-prototype-poisoning-2610fa170061) 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.\n\n**Fast fallback to input if is not string:**\n\n```js\n// Uncaught SyntaxError: Unexpected token u in JSON at position 0\nJSON.parse()\n\n// undefined\ndestr()\n```\n\n```js\n// JSON.parse x 5,324,474 ops/sec ±0.65% (94 runs sampled)\nJSON.parse(3.14159265359)\n\n// destr x 657,187,095 ops/sec ±0.06% (98 runs sampled)\ndestr(3.14159265359)\n```\n\n**Fast lookup for known string values:**\n\n```js\n// Uncaught SyntaxError: Unexpected token T in JSON at position 0\nJSON.parse('TRUE')\n\n// true\ndestr('TRUE')\n```\n\n```js\n// JSON.parse x 10,407,488 ops/sec ±0.30% (97 runs sampled)\nJSON.parse('true')\n\n// destr x 88,634,032 ops/sec ±0.32% (95 runs sampled)\ndestr('true')\n```\n\n**Fallback to original value if parse fails (empty or any plain string):**\n\n```js\n// Uncaught SyntaxError: Unexpected token s in JSON at position 0\n// JSON.parse (try-catch) x 248,212 ops/sec ±1.22% (84 runs sampled\nJSON.parse('salam')\n\n// destr x 30,867,179 ops/sec ±0.49% (94 runs sampled)\ndestr('salam')\n```\n\n**Avoid prototype pollution:**\n\n```js\nconst input = '{ \"user\": { \"__proto__\": { \"isAdmin\": true } } }'\n\n// { user: { __proto__: { isAdmin: true } } }\nJSON.parse(input)\n\n// { user: {} }\ndestr(input)\n```\n\n## License\n\nMIT. Made with 💖\n\n<!-- Refs -->\n[npm-v-src]: https://img.shields.io/npm/v/destr?style=flat-square\n[npm-v-href]: https://npmjs.com/package/destr\n\n[npm-d-src]: https://img.shields.io/npm/dm/destr?style=flat-square\n[npm-d-href]: https://npmjs.com/package/destr\n\n[github-actions-src]: https://img.shields.io/github/workflow/status/unjs/destr/ci/master?style=flat-square\n[github-actions-href]: https://github.com/unjs/destr/actions?query=workflow%3Aci\n\n[bundlephobia-src]: https://img.shields.io/bundlephobia/min/destr?style=flat-square\n[bundlephobia-href]: https://bundlephobia.com/result?p=destr\n" | ||
"readme": "# destr\n\n> A faster, secure and convenient alternative for [`JSON.parse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse):\n\n[![npm version][npm-v-src]][npm-v-href]\n[![npm downloads][npm-d-src]][npm-d-href]\n[![bundle phobia][bundlephobia-src]][bundlephobia-href]\n\n## Usage\n\n### Node.js\n\nInstall using npm or yarn:\n\n```bash\nnpm i destr\n# or\nyarn add destr\n```\n\nImport into your Node.js project:\n\n```js\n// CommonJS\nconst destr = require('destr')\n\n// ESM\nimport destr from 'destr'\n```\n\n### Deno\n\n```js\nimport destr from 'https://deno.land/x/destr/src/index.ts'\n\nconsole.log(destr('{ \"deno\": \"yay\" }'))\n```\n\n### Options\n\n`destr` allows the following options as the second argument:\n\n#### `strict`\n\nDefault: `false`\n\nIf set to `true`, `destr` will throw an error if the input is not a valid JSON string or parsing fails.\n\n```js\n// Returns \"[foo\"\ndestr('[foo')\n\n// Throws an error\ndestr('[foo', { strict: true })\n```\n\n## Why?\n\nPlease note that `destr` is little bit slower when parsing a standard JSON string mainly because of transform to avoid [prototype pollution](https://hueniverse.com/a-tale-of-prototype-poisoning-2610fa170061) 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.\n\n**Fast fallback to input if is not string:**\n\n```js\n// Uncaught SyntaxError: Unexpected token u in JSON at position 0\nJSON.parse()\n\n// undefined\ndestr()\n```\n\n**Fast lookup for known string values:**\n\n```js\n// Uncaught SyntaxError: Unexpected token T in JSON at position 0\nJSON.parse('TRUE')\n\n// true\ndestr('TRUE')\n```\n\n**Fallback to original value if parse fails (empty or any plain string):**\n\n```js\n// Uncaught SyntaxError: Unexpected token s in JSON at position 0\nJSON.parse('salam')\n\n// \"salam\"\ndestr('salam')\n```\n\n**Avoid prototype pollution:**\n\n```js\nconst input = '{ \"user\": { \"__proto__\": { \"isAdmin\": true } } }'\n\n// { user: { __proto__: { isAdmin: true } } }\nJSON.parse(input)\n\n// { user: {} }\ndestr(input)\n```\n\n## Benchmarks\n\nLocally try with `pnpm benchmark`\n\nResults on Node.js 18.11.0 with MBA M2\n\n```\n=== Non-string fallback ==\nJSON.parse x 10,323,718 ops/sec ±0.45% (96 runs sampled)\ndestr x 1,057,268,114 ops/sec ±1.71% (90 runs sampled)\ndestr (strict) x 977,215,995 ops/sec ±1.43% (97 runs sampled)\nsjson:\n@hapi/bourne x 10,151,985 ops/sec ±0.76% (96 runs sampled)\nFastest is destr\n\n=== Known values ==\nJSON.parse x 16,359,358 ops/sec ±0.90% (92 runs sampled)\ndestr x 107,849,085 ops/sec ±0.34% (97 runs sampled)\ndestr (strict) x 107,891,427 ops/sec ±0.34% (99 runs sampled)\nsjson x 14,216,957 ops/sec ±0.98% (89 runs sampled)\n@hapi/bourne x 15,209,152 ops/sec ±1.08% (88 runs sampled)\nFastest is destr (strict),destr\n\n=== Plain string ==\nJSON.parse (try-catch) x 211,560 ops/sec ±0.84% (92 runs sampled)\ndestr x 60,315,113 ops/sec ±0.46% (98 runs sampled)\ndestr (strict):\nsjson (try-catch) x 186,492 ops/sec ±0.70% (97 runs sampled)\n@hapi/bourne:\nFastest is destr\n\n=== standard object ==\nJSON.parse x 492,180 ops/sec ±0.98% (98 runs sampled)\ndestr x 356,819 ops/sec ±0.40% (98 runs sampled)\ndestr (strict) x 412,955 ops/sec ±0.88% (94 runs sampled)\nsjson x 437,376 ops/sec ±0.42% (102 runs sampled)\n@hapi/bourne x 457,020 ops/sec ±0.81% (99 runs sampled)\nFastest is JSON.parse\n\n=== invalid syntax ==\nJSON.parse (try-catch) x 493,739 ops/sec ±0.51% (98 runs sampled)\ndestr x 405,848 ops/sec ±0.56% (100 runs sampled)\ndestr (strict) x 409,514 ops/sec ±0.57% (101 runs sampled)\nsjson (try-catch) x 435,406 ops/sec ±0.41% (100 runs sampled)\n@hapi/bourne x 467,163 ops/sec ±0.42% (99 runs sampled)\nFastest is JSON.parse (try-catch)\n```\n\n## License\n\nMIT. Made with 💖\n\n<!-- Refs -->\n[npm-v-src]: https://img.shields.io/npm/v/destr?style=flat-square\n[npm-v-href]: https://npmjs.com/package/destr\n\n[npm-d-src]: https://img.shields.io/npm/dm/destr?style=flat-square\n[npm-d-href]: https://npmjs.com/package/destr\n\n[github-actions-src]: https://img.shields.io/github/workflow/status/unjs/destr/ci/master?style=flat-square\n[github-actions-href]: https://github.com/unjs/destr/actions?query=workflow%3Aci\n\n[bundlephobia-src]: https://img.shields.io/bundlephobia/min/destr?style=flat-square\n[bundlephobia-href]: https://bundlephobia.com/result?p=destr\n" | ||
} |
@@ -39,2 +39,20 @@ # destr | ||
### Options | ||
`destr` allows the following options as the second argument: | ||
#### `strict` | ||
Default: `false` | ||
If set to `true`, `destr` will throw an error if the input is not a valid JSON string or parsing fails. | ||
```js | ||
// Returns "[foo" | ||
destr('[foo') | ||
// Throws an error | ||
destr('[foo', { strict: true }) | ||
``` | ||
## Why? | ||
@@ -54,10 +72,2 @@ | ||
```js | ||
// JSON.parse x 5,324,474 ops/sec ±0.65% (94 runs sampled) | ||
JSON.parse(3.14159265359) | ||
// destr x 657,187,095 ops/sec ±0.06% (98 runs sampled) | ||
destr(3.14159265359) | ||
``` | ||
**Fast lookup for known string values:** | ||
@@ -73,10 +83,2 @@ | ||
```js | ||
// JSON.parse x 10,407,488 ops/sec ±0.30% (97 runs sampled) | ||
JSON.parse('true') | ||
// destr x 88,634,032 ops/sec ±0.32% (95 runs sampled) | ||
destr('true') | ||
``` | ||
**Fallback to original value if parse fails (empty or any plain string):** | ||
@@ -86,6 +88,5 @@ | ||
// Uncaught SyntaxError: Unexpected token s in JSON at position 0 | ||
// JSON.parse (try-catch) x 248,212 ops/sec ±1.22% (84 runs sampled | ||
JSON.parse('salam') | ||
// destr x 30,867,179 ops/sec ±0.49% (94 runs sampled) | ||
// "salam" | ||
destr('salam') | ||
@@ -106,2 +107,50 @@ ``` | ||
## Benchmarks | ||
Locally try with `pnpm benchmark` | ||
Results on Node.js 18.11.0 with MBA M2 | ||
``` | ||
=== Non-string fallback == | ||
JSON.parse x 10,323,718 ops/sec ±0.45% (96 runs sampled) | ||
destr x 1,057,268,114 ops/sec ±1.71% (90 runs sampled) | ||
destr (strict) x 977,215,995 ops/sec ±1.43% (97 runs sampled) | ||
sjson: | ||
@hapi/bourne x 10,151,985 ops/sec ±0.76% (96 runs sampled) | ||
Fastest is destr | ||
=== Known values == | ||
JSON.parse x 16,359,358 ops/sec ±0.90% (92 runs sampled) | ||
destr x 107,849,085 ops/sec ±0.34% (97 runs sampled) | ||
destr (strict) x 107,891,427 ops/sec ±0.34% (99 runs sampled) | ||
sjson x 14,216,957 ops/sec ±0.98% (89 runs sampled) | ||
@hapi/bourne x 15,209,152 ops/sec ±1.08% (88 runs sampled) | ||
Fastest is destr (strict),destr | ||
=== Plain string == | ||
JSON.parse (try-catch) x 211,560 ops/sec ±0.84% (92 runs sampled) | ||
destr x 60,315,113 ops/sec ±0.46% (98 runs sampled) | ||
destr (strict): | ||
sjson (try-catch) x 186,492 ops/sec ±0.70% (97 runs sampled) | ||
@hapi/bourne: | ||
Fastest is destr | ||
=== standard object == | ||
JSON.parse x 492,180 ops/sec ±0.98% (98 runs sampled) | ||
destr x 356,819 ops/sec ±0.40% (98 runs sampled) | ||
destr (strict) x 412,955 ops/sec ±0.88% (94 runs sampled) | ||
sjson x 437,376 ops/sec ±0.42% (102 runs sampled) | ||
@hapi/bourne x 457,020 ops/sec ±0.81% (99 runs sampled) | ||
Fastest is JSON.parse | ||
=== invalid syntax == | ||
JSON.parse (try-catch) x 493,739 ops/sec ±0.51% (98 runs sampled) | ||
destr x 405,848 ops/sec ±0.56% (100 runs sampled) | ||
destr (strict) x 409,514 ops/sec ±0.57% (101 runs sampled) | ||
sjson (try-catch) x 435,406 ops/sec ±0.41% (100 runs sampled) | ||
@hapi/bourne x 467,163 ops/sec ±0.42% (99 runs sampled) | ||
Fastest is JSON.parse (try-catch) | ||
``` | ||
## License | ||
@@ -108,0 +157,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
13867
8
108
167