Skip to content

Commit

Permalink
5.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
AFatNiBBa committed Oct 18, 2021
1 parent 183211a commit a9d5960
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 21 deletions.
45 changes: 28 additions & 17 deletions main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

/*
[WIP]: doc (eng)
[WIP]: comment (eng)
[WIP]: {function,object,array}.{get,set}
[/!\]: le proprietà gestite di oggetti gestiti non vengono salvate anche se sovrascritte dall'utente
[/!\]: "__proto__" proprietà asestante e non getter/setter di "Object.prototype" setta comunque il prototipo
Expand Down Expand Up @@ -32,21 +32,23 @@ var uneval = (typeof module === "undefined" ? {} : module).exports = (function (
opts.method ??= true;
opts.proxy ??= true;
opts.proto ??= true;
opts.depth ??= Infinity;
opts.call = (opts.call ?? true) || "";
opts.safe ??= true;
opts.func ??= true;
opts.val ??= "x";

//[ Wrapping con funzione se serve la cache e/o la funzione di assegnazione ]
opts.assign = "";
opts.references = 0;
//[ Wrapping con funzione se "opts.call" è attivo e/o se serve la cache e/o la funzione di assegnazione ]
opts.stats = { assign: "", references: 0, depth: 0 };
var out = uneval.source(obj, uneval.scan(obj, opts), opts, level);
const wrap = !opts.call || (opts.func && (opts.stats.references || opts.stats.assign));
if (
obj instanceof Function && obj.name && opts.safe ||
out[0] == "{" && (opts.safe || (opts.references && opts.func))
obj instanceof Function && obj.name && opts.safe || // Forces named functions to be expressions and not statements
out[0] == "{" && (opts.safe || wrap)
) out = `(${ out })`;
return opts.func && (opts.references || opts.assign)
? `(${ opts.val }${ opts.space }=>${ opts.space }${ out })({${ opts.assign && `${ opts.space }assign:${ opts.space }${ uneval.utils.assign }${ opts.space }` }})`
: out;
return wrap
? `((${ opts.val }${ opts.space }=${ opts.space }{${ opts.stats.assign && `${ opts.space }assign:${ opts.space }${ uneval.utils.assign }${ opts.space }` }})${ opts.space }=>${ opts.space }${ out })${ opts.call && "()" }`
: out;
}

/**
Expand Down Expand Up @@ -143,10 +145,16 @@ var uneval = (typeof module === "undefined" ? {} : module).exports = (function (
}
if (opts.custom && obj?.[utils.customScan] instanceof Function)
return obj[utils.customScan](out, opts, cache, prev, parent, uneval);
else if (obj instanceof Symbol) // Scan parte primitiva
else if (obj instanceof Symbol) // Scan parte primitiva symbol
out.delegate = utils.Delegate.from(obj.valueOf(), opts, cache); // Non serve "prev", tanto un simbolo non ha sotto-proprietà da salvare
else if (obj instanceof Map || obj instanceof Set)
else if (obj instanceof Set)
out.delegate = utils.Delegate.from([ ...obj ], opts, cache, next);
else if (obj instanceof Map)
{
opts.stats.depth--;
out.delegate = utils.Delegate.from([ ...obj ], opts, cache, next);
opts.stats.depth++;
}
else if (obj?.constructor instanceof Function && obj.constructor?.prototype === obj)
{
out.delegate = utils.Delegate.from(obj.constructor, opts, cache, false); // "prev" è impostato su 'false' per far saltare le proprietà statiche a "uneval.scan()"
Expand All @@ -166,13 +174,15 @@ var uneval = (typeof module === "undefined" ? {} : module).exports = (function (
// [ Scanning sotto proprietà ]
if (prev !== false && obj !== globalThis && (type === "object" || type === "function"))
{
opts.stats.depth++;
const managed = utils.managedProtos.get(obj.__proto__);
for (const k of Reflect.ownKeys(obj).concat("__proto__"))
{
//[ Salta la proprietà ]
const v = obj[k];
if ((k === "__proto__" && (!opts.proto || managed)) || managed?.(k))
continue;
if (
(v instanceof Object && opts.stats.depth >= opts.depth) || // Salta se è oltre "opts.depth"
((k === "__proto__" && (!opts.proto || managed)) || managed?.(k)) // Salta la proprietà
) continue;

//[ Struttura chiave e valore ]
const kS = uneval.scan(k, opts, cache, next);
Expand All @@ -183,6 +193,7 @@ var uneval = (typeof module === "undefined" ? {} : module).exports = (function (
else if (prev?.(new utils.Circular(k, kS, out, v)));
else if (!vS?.skip) out.sub.set(k, [ kS, vS ]); // La chiave viene salvata solo se non si tratta di un riferimento circolare
}
opts.stats.depth--;
}
return out;
}
Expand All @@ -203,7 +214,7 @@ var uneval = (typeof module === "undefined" ? {} : module).exports = (function (
customScan,
customSource,
method: /^(async\s+)?([\["*]|(?!\w+\s*=>|\(|function\W|class(?!\s*\()\W))/,
assign: (a,b)=>Object.defineProperties(a,Object.getOwnPropertyDescriptors(b)), // Se serve le funzioni impostano "opts.assign" su 'true'
assign: (a,b)=>Object.defineProperties(a,Object.getOwnPropertyDescriptors(b)), // Se serve le funzioni impostano "opts.stats.assign" su 'true'
showFormatting: { space: "\x1b[101m \x1b[0m", tab: "\x1b[104m \x1b[0m", endl: "\x1b[105m \n\x1b[0m" },
managedProtos: new Map((cache => [
[ globalThis.Buffer, x => uneval.utils.index(x) ],
Expand Down Expand Up @@ -233,7 +244,7 @@ var uneval = (typeof module === "undefined" ? {} : module).exports = (function (
cir = []; // Lista dei riferimenti circolari che fanno riferimento all'oggetto
sub = new Map(); // Oggetto che mappa le proprietà dell'oggetto con una coppia di oggetti che rappresentano la struttura rispettivamente della chiave e del valore della proprietà
delegate; // Eventuale coppia valore-struct che rappresenterà l'oggetto corrente
ref(opts) { return this.id ||= ++opts.references; }
ref(opts) { return this.id ||= ++opts.stats.references; }
},

/**
Expand Down Expand Up @@ -491,7 +502,7 @@ var uneval = (typeof module === "undefined" ? {} : module).exports = (function (
{
const out = temp.length ? `{${ g }${ temp.join("," + g) }${ gl }}` : "{}";
return managed
? opts.assign = `${ opts.val }.assign(${ t }${ managed },${ t }${ out }${ tl })`
? opts.stats.assign = `${ opts.val }.assign(${ t }${ managed },${ t }${ out }${ tl })`
: out;
}
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "uneval.js",
"version": "5.2.6",
"version": "5.3.0",
"description": "Convert an object to its source code (With references and PROXIES too!)",
"main": "main.js",
"scripts": {
Expand Down
15 changes: 12 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ console.log(uneval(a, { tab: " " }));
```
And the output will be
```js
(x => (
((x = {}) => (
x[1] = {
c: x[2] = {
url: /^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$/gi
Expand All @@ -45,7 +45,7 @@ And the output will be
},
x[2].a = x[1],
x[1].e = x[1]
))({})
))()
```
Note that the complexity of the output depends on the complexity of the input
```js
Expand Down Expand Up @@ -100,6 +100,12 @@ The available options are:
- **`proto`**
- Saves the class of objects (Including the `__proto__` property)
- It defaults to `true`
- **`depth`**
- If not `Infinity` specifies the maximum depth in which the object should be serialized
- It defaults to `Infinity`
- **`call`**
- If `false` wraps forcibly the result in a function but doesn't evaluate it
- It defaults to `true`
- **`safe`**
- Wraps object literals in brackets to not confuse them with blocks
- It's always `true` if the object is in the wrapper function
Expand All @@ -119,6 +125,9 @@ The available options are:
- The code that will be put in front of the object source
- If it is an object then the value of the property `pre` will be concatenated before the object while the value of `post` will be concatenated after
- It defaults to `"module.exports = "`, the spaces will be the ones defined in the options
- **`stats`**
- Not an option
- Its an object containing stats on the last execution (If you keep the settings object) and its necessary for the `uneval()` function
Note that in every option which accepts a boolean you can put `0` to represent `false` and everything not "falsy" to represent `true`.
Expand Down Expand Up @@ -183,7 +192,7 @@ Note that in every option which accepts a boolean you can put `0` to represent `
> ```
> Custom without scan:
> ```js
> (x=>[Object.setPrototypeOf(new NumArray(1,2,3),(class NumArray extends Array { value = "test" }).prototype),x[1]])({})
> ((x={})=>[Object.setPrototypeOf(new NumArray(1,2,3),(class NumArray extends Array { value = "test" }).prototype),x[1]])()
> ```
> If you execute them you will notice that on the custom one that has not the scan defined there is a reference (`x[1]`) that is not defined anywhere, and it scanned the prototype of `NumArray` including it in the generated source, which is redundant.
- Custom definitions
Expand Down

0 comments on commit a9d5960

Please sign in to comment.