Skip to content

fix: devalue will return private data to the client even if toJSON is implemented. #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 44 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const logLimit = parseInt(process.env.NUXT_ENV_DEVALUE_LOG_LIMIT) || 99;

export default function devalue(value: any, level = defaultLogLevel) {
const counts = new Map();
const mapObjToJSON = new Map();

let logNum = 0;

Expand All @@ -35,7 +36,7 @@ export default function devalue(value: any, level = defaultLogLevel) {
}


function walk(thing: any) {
function walk(thing: any, parent:any, key:string, index:number) {
if (typeof thing === 'function') {
consola[level](`Cannot stringify a function ${thing.name}`)
return
Expand All @@ -60,15 +61,53 @@ export default function devalue(value: any, level = defaultLogLevel) {
return;

case 'Array':
thing.forEach(walk);
thing.forEach((item:any, index:number)=>{walk(item, parent, key, index)});
break;

case 'Set':
case 'Map':
Array.from(thing).forEach(walk);
Array.from(thing).forEach((item, index)=>{walk(item, parent,key, undefined)});
break;

default:
if (thing && thing.toJSON) {
//remove it from existing counts map so we can come here again to replace.
counts.delete(thing);

let json;
if( mapObjToJSON.has(thing) ){
json = mapObjToJSON.get(thing);

//increment the count as it used to do for "thing"
counts.set(json, counts.get(json) + 1);
}
else
{
json = thing.toJSON();
if (getType(json) === 'String') {
// Try to parse the returned data
try {
json = JSON.parse(json);
}
catch (e) {
json = thing;
}
}

//add to map object in case the object is referenced again
mapObjToJSON.set(thing, json);

//set the count first time
counts.set(json, 1)
}

if(typeof index !== 'undefined')
parent[key][index] = json;
else
parent[key] = json;
return;
}

const proto = Object.getPrototypeOf(thing);

if (
Expand All @@ -82,14 +121,14 @@ export default function devalue(value: any, level = defaultLogLevel) {
} else if (Object.getOwnPropertySymbols(thing).length > 0) {
log(`Cannot stringify POJOs with symbolic keys ${Object.getOwnPropertySymbols(thing).map(symbol => symbol.toString())}`);
} else {
Object.keys(thing).forEach(key => walk(thing[key]));
Object.keys(thing).forEach(function (key) { return walk(thing[key], thing, key, undefined); });
}

}
}
}

walk(value);
walk(value, undefined, undefined, undefined);

const names = new Map();
Array.from(counts)
Expand Down