Skip to content

Instantly share code, notes, and snippets.

@emptyother
Last active October 22, 2019 04:45
Show Gist options
  • Save emptyother/f76a6deebf497a598d1aa85a8553260e to your computer and use it in GitHub Desktop.
Save emptyother/f76a6deebf497a598d1aa85a8553260e to your computer and use it in GitHub Desktop.
runtime_reflection.js
/**
* Reads a object at runtime and serializes it into metadata.
* Need serious improvements, but does some of the work.
* @returns metadata.
* @returns typescript definition text.
*/
function (targetvar){
// TODO: Find a way to recognize a class from a function.
// TODO: Find out how to detect arrays (should be easy).
// TODO: Create separate interfaces instead of a nested interface.
// TODO: Formatted output (tabs right now is a bit wonky).
clear();
var maxdepth = 2;
class Metadata {
constructor(target, curdepth) {
if (typeof target === 'undefined' || target === null)
return;
this.name = capitalize(target.name);
this.curdepth = curdepth;
curdepth++;
this.list = [];
for (const [key,value] of Object.entries(target)) {
this.list.push({
key,
type: typeof value,
isNewable: isNewable(value),
children: typeof value === 'object' && curdepth <= maxdepth ? new Metadata(value,curdepth) : undefined,
isArray: Array.isArray(value),
curdepth,
value
});
}
}
toString() {
const returnstr = [];
returnstr.push('{');
if (typeof this.list !== 'undefined') {
for (const i of this.list) {
const rstr = [];
rstr.push(i.key + ": ");
if (i.isNewable) {
rstr.push(capitalize(i.key) + ';');
} else if (typeof i.value === 'object') {
if (typeof i.children !== 'undefined') {
rstr.push(i.children.toString());
}
} else {
rstr.push(i.type + ";");
}
returnstr.push('\t' + rstr.join(''));
}
}
returnstr.push('};');
return returnstr.join('\n' + tabs(this.curdepth));
}
}
function tabs(num) {
const rstr = [];
for(let f = 0; f <= num; f++) {
rstr.push('\t');
}
return rstr.join('');
}
function capitalize(s) {
if (typeof s !== 'string')
return ''
return s.charAt(0).toUpperCase() + s.slice(1)
}
function isNewable(value) {
try {
const f = new value();
} catch (err) {
if (err.message.indexOf("is not a constructor") > -1) {
return false;
}
}
return true;
}
const m = new Metadata(targetvar,0);
return {
metadata: m,
definition: m.toString(),
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment