initial commit
This commit is contained in:
21
node_modules/destr/LICENSE
generated
vendored
Normal file
21
node_modules/destr/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Pooya Parsa <pooya@pi0.io>
|
||||
|
||||
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.
|
||||
159
node_modules/destr/README.md
generated
vendored
Normal file
159
node_modules/destr/README.md
generated
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
# 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?
|
||||
|
||||
**Fast fallback to input if is not string:**
|
||||
|
||||
```js
|
||||
// Uncaught SyntaxError: Unexpected token u in JSON at position 0
|
||||
JSON.parse()
|
||||
|
||||
// undefined
|
||||
destr()
|
||||
```
|
||||
|
||||
**Fast lookup for known string values:**
|
||||
|
||||
```js
|
||||
// Uncaught SyntaxError: Unexpected token T in JSON at position 0
|
||||
JSON.parse('TRUE')
|
||||
|
||||
// true
|
||||
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('salam')
|
||||
|
||||
// "salam"
|
||||
destr('salam')
|
||||
```
|
||||
|
||||
**Avoid prototype pollution:**
|
||||
|
||||
```js
|
||||
const input = '{ "user": { "__proto__": { "isAdmin": true } } }'
|
||||
|
||||
// { user: { __proto__: { isAdmin: true } } }
|
||||
JSON.parse(input)
|
||||
|
||||
// { user: {} }
|
||||
destr(input)
|
||||
```
|
||||
|
||||
### Strict Mode
|
||||
|
||||
If `{ strict: true }` passed as second argument, `destr` 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)
|
||||
|
||||
```js
|
||||
// Returns "[foo"
|
||||
destr('[foo')
|
||||
|
||||
// Throws an error
|
||||
destr('[foo', { strict: true })
|
||||
```
|
||||
|
||||
## Benchmarks
|
||||
|
||||
Locally try with `pnpm benchmark`. Below are esults on Node.js 18.11.0 with MBA M2.
|
||||
|
||||
**Note** `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.
|
||||
|
||||
```
|
||||
=== 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
|
||||
|
||||
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
|
||||
57
node_modules/destr/dist/index.cjs
generated
vendored
Normal file
57
node_modules/destr/dist/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
'use strict';
|
||||
|
||||
const suspectProtoRx = /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\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 = /^\s*["[{]|^\s*-?\d[\d.]{0,14}\s*$/;
|
||||
function jsonParseTransform(key, value) {
|
||||
if (key === "__proto__") {
|
||||
return;
|
||||
}
|
||||
if (key === "constructor" && value && typeof value === "object" && "prototype" in value) {
|
||||
return;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function destr(value, options = {}) {
|
||||
if (typeof value !== "string") {
|
||||
return value;
|
||||
}
|
||||
const _lval = value.toLowerCase().trim();
|
||||
if (_lval === "true") {
|
||||
return true;
|
||||
}
|
||||
if (_lval === "false") {
|
||||
return false;
|
||||
}
|
||||
if (_lval === "null") {
|
||||
return null;
|
||||
}
|
||||
if (_lval === "nan") {
|
||||
return Number.NaN;
|
||||
}
|
||||
if (_lval === "infinity") {
|
||||
return Number.POSITIVE_INFINITY;
|
||||
}
|
||||
if (_lval === "undefined") {
|
||||
return void 0;
|
||||
}
|
||||
if (!JsonSigRx.test(value)) {
|
||||
if (options.strict) {
|
||||
throw new SyntaxError("Invalid JSON");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
try {
|
||||
if (suspectProtoRx.test(value) || suspectConstructorRx.test(value)) {
|
||||
return JSON.parse(value, jsonParseTransform);
|
||||
}
|
||||
return JSON.parse(value);
|
||||
} catch (error) {
|
||||
if (options.strict) {
|
||||
throw error;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = destr;
|
||||
6
node_modules/destr/dist/index.d.ts
generated
vendored
Normal file
6
node_modules/destr/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
type Options = {
|
||||
strict?: boolean;
|
||||
};
|
||||
declare function destr(value: any, options?: Options): any;
|
||||
|
||||
export { Options, destr as default };
|
||||
55
node_modules/destr/dist/index.mjs
generated
vendored
Normal file
55
node_modules/destr/dist/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
const suspectProtoRx = /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\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 = /^\s*["[{]|^\s*-?\d[\d.]{0,14}\s*$/;
|
||||
function jsonParseTransform(key, value) {
|
||||
if (key === "__proto__") {
|
||||
return;
|
||||
}
|
||||
if (key === "constructor" && value && typeof value === "object" && "prototype" in value) {
|
||||
return;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function destr(value, options = {}) {
|
||||
if (typeof value !== "string") {
|
||||
return value;
|
||||
}
|
||||
const _lval = value.toLowerCase().trim();
|
||||
if (_lval === "true") {
|
||||
return true;
|
||||
}
|
||||
if (_lval === "false") {
|
||||
return false;
|
||||
}
|
||||
if (_lval === "null") {
|
||||
return null;
|
||||
}
|
||||
if (_lval === "nan") {
|
||||
return Number.NaN;
|
||||
}
|
||||
if (_lval === "infinity") {
|
||||
return Number.POSITIVE_INFINITY;
|
||||
}
|
||||
if (_lval === "undefined") {
|
||||
return void 0;
|
||||
}
|
||||
if (!JsonSigRx.test(value)) {
|
||||
if (options.strict) {
|
||||
throw new SyntaxError("Invalid JSON");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
try {
|
||||
if (suspectProtoRx.test(value) || suspectConstructorRx.test(value)) {
|
||||
return JSON.parse(value, jsonParseTransform);
|
||||
}
|
||||
return JSON.parse(value);
|
||||
} catch (error) {
|
||||
if (options.strict) {
|
||||
throw error;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
export { destr as default };
|
||||
42
node_modules/destr/package.json
generated
vendored
Normal file
42
node_modules/destr/package.json
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "destr",
|
||||
"version": "1.2.2",
|
||||
"description": "A faster, secure and convenient alternative for JSON.parse",
|
||||
"repository": "unjs/destr",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.mjs",
|
||||
"require": "./dist/index.cjs"
|
||||
}
|
||||
},
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@hapi/bourne": "^3.0.0",
|
||||
"@vitest/coverage-c8": "^0.25.3",
|
||||
"benchmark": "^2.1.4",
|
||||
"eslint": "^8.29.0",
|
||||
"eslint-config-unjs": "^0.0.2",
|
||||
"secure-json-parse": "^2.6.0",
|
||||
"standard-version": "^9.5.0",
|
||||
"typescript": "^4.9.3",
|
||||
"unbuild": "^1.0.1",
|
||||
"vitest": "^0.25.3"
|
||||
},
|
||||
"packageManager": "pnpm@7.18.0",
|
||||
"scripts": {
|
||||
"bench": "pnpm build && node ./bench.cjs",
|
||||
"build": "unbuild",
|
||||
"dev": "vitest dev",
|
||||
"lint": "eslint --ext .ts .",
|
||||
"release": "pnpm test && pnpm build && standard-version && git push --follow-tags && pnpm publish",
|
||||
"test": "pnpm lint && vitest run --coverage"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user