This commit is contained in:
2022-07-21 03:28:35 +00:00
parent d7c883d6df
commit 51b34b0e1d
30103 changed files with 4152204 additions and 23 deletions
Generated Vendored
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) UnJS
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+117
View File
@@ -0,0 +1,117 @@
# destr
> A faster, secure and convenient alternative for [`JSON.parse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse):
[![npm version][npm-v-src]][npm-v-href]
[![npm downloads][npm-d-src]][npm-d-href]
[![bundle phobia][bundlephobia-src]][bundlephobia-href]
## Usage
### Node.js
Install using npm or yarn:
```bash
npm i destr
# or
yarn add destr
```
Import into your Node.js project:
```js
// CommonJS
const destr = require('destr')
// ESM
import destr from 'destr'
```
### Deno
```js
import destr from 'https://deno.land/x/destr/src/index.ts'
console.log(destr('{ "deno": "yay" }'))
```
## Why?
Please 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.
**Fast fallback to input if is not string:**
```js
// Uncaught SyntaxError: Unexpected token u in JSON at position 0
JSON.parse()
// undefined
destr()
```
```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:**
```js
// Uncaught SyntaxError: Unexpected token T in JSON at position 0
JSON.parse('TRUE')
// true
destr('TRUE')
```
```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):**
```js
// 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)
destr('salam')
```
**Avoid prototype pollution:**
```js
const input = '{ "user": { "__proto__": { "isAdmin": true } } }'
// { user: { __proto__: { isAdmin: true } } }
JSON.parse(input)
// { user: {} }
destr(input)
```
## License
MIT. Made with 💖
<!-- Refs -->
[npm-v-src]: https://img.shields.io/npm/v/destr?style=flat-square
[npm-v-href]: https://npmjs.com/package/destr
[npm-d-src]: https://img.shields.io/npm/dm/destr?style=flat-square
[npm-d-href]: https://npmjs.com/package/destr
[github-actions-src]: https://img.shields.io/github/workflow/status/unjs/destr/ci/master?style=flat-square
[github-actions-href]: https://github.com/unjs/destr/actions?query=workflow%3Aci
[bundlephobia-src]: https://img.shields.io/bundlephobia/min/destr?style=flat-square
[bundlephobia-href]: https://bundlephobia.com/result?p=destr
+48
View File
@@ -0,0 +1,48 @@
'use strict';
const suspectProtoRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/;
const suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
const JsonSigRx = /^["{[]|^-?[0-9][0-9.]{0,14}$/;
function jsonParseTransform(key, value) {
if (key === "__proto__" || key === "constructor") {
return;
}
return value;
}
function destr(val) {
if (typeof val !== "string") {
return val;
}
const _lval = val.toLowerCase();
if (_lval === "true") {
return true;
}
if (_lval === "false") {
return false;
}
if (_lval === "null") {
return null;
}
if (_lval === "nan") {
return NaN;
}
if (_lval === "infinity") {
return Infinity;
}
if (_lval === "undefined") {
return void 0;
}
if (!JsonSigRx.test(val)) {
return val;
}
try {
if (suspectProtoRx.test(val) || suspectConstructorRx.test(val)) {
return JSON.parse(val, jsonParseTransform);
}
return JSON.parse(val);
} catch (_e) {
return val;
}
}
module.exports = destr;
+3
View File
@@ -0,0 +1,3 @@
declare function destr(val: any): any;
export { destr as default };
+46
View File
@@ -0,0 +1,46 @@
const suspectProtoRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/;
const suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
const JsonSigRx = /^["{[]|^-?[0-9][0-9.]{0,14}$/;
function jsonParseTransform(key, value) {
if (key === "__proto__" || key === "constructor") {
return;
}
return value;
}
function destr(val) {
if (typeof val !== "string") {
return val;
}
const _lval = val.toLowerCase();
if (_lval === "true") {
return true;
}
if (_lval === "false") {
return false;
}
if (_lval === "null") {
return null;
}
if (_lval === "nan") {
return NaN;
}
if (_lval === "infinity") {
return Infinity;
}
if (_lval === "undefined") {
return void 0;
}
if (!JsonSigRx.test(val)) {
return val;
}
try {
if (suspectProtoRx.test(val) || suspectConstructorRx.test(val)) {
return JSON.parse(val, jsonParseTransform);
}
return JSON.parse(val);
} catch (_e) {
return val;
}
}
export { destr as default };
+77
View File
@@ -0,0 +1,77 @@
{
"_args": [
[
"destr@1.1.1",
"/home/node/nuxt"
]
],
"_from": "destr@1.1.1",
"_id": "destr@1.1.1",
"_inBundle": false,
"_integrity": "sha512-QqkneF8LrYmwATMdnuD2MLI3GHQIcBnG6qFC2q9bSH430VTCDAVjcspPmUaKhPGtAtPAftIUFqY1obQYQuwmbg==",
"_location": "/destr",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "destr@1.1.1",
"name": "destr",
"escapedName": "destr",
"rawSpec": "1.1.1",
"saveSpec": null,
"fetchSpec": "1.1.1"
},
"_requiredBy": [
"/@nuxt/cli",
"/@nuxt/config",
"/@nuxt/telemetry",
"/rc9"
],
"_resolved": "https://registry.npmjs.org/destr/-/destr-1.1.1.tgz",
"_spec": "1.1.1",
"_where": "/home/node/nuxt",
"bugs": {
"url": "https://github.com/unjs/destr/issues"
},
"description": "A faster, secure and convenient alternative for JSON.parse",
"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"
},
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
},
"files": [
"dist"
],
"homepage": "https://github.com/unjs/destr#readme",
"license": "MIT",
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"name": "destr",
"packageManager": "pnpm@6.32.3",
"repository": {
"type": "git",
"url": "git+https://github.com/unjs/destr.git"
},
"scripts": {
"bench": "pnpm build && node ./bench.cjs",
"build": "unbuild",
"lint": "eslint --ext .ts .",
"release": "pnpm test && pnpm build && standard-version && git push --follow-tags && pnpm publish",
"test": "pnpm lint"
},
"type": "module",
"types": "dist/index.d.ts",
"version": "1.1.1"
}