Last active
February 29, 2020 16:07
-
-
Save samuelmaddock/fb54ddc47b7a958ded1f799861239a87 to your computer and use it in GitHub Desktop.
Dumps a TypeScript-like JSON interface of runtime JavaScript objects.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; (function (targetObj) { | |
const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm | |
const ARGUMENT_NAMES = /([^\s,]+)/g | |
const getParamNames = func => { | |
var fnStr = func.toString().replace(STRIP_COMMENTS, '') | |
var result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES) | |
if (result === null) result = [] | |
return result | |
} | |
const isClassName = str => str.length > 0 ? str[0] === str[0].toUpperCase() : false | |
const isPrivateName = str => str.length <= 2 | |
const constructorType = func => `(${getParamNames(func).join(', ')}) => any` | |
const jsonFunctionType = (name, func) => { | |
const interfaceObj = {} | |
// Constructor | |
if (typeof name === 'string' && isClassName(name)) { | |
interfaceObj['new'] = constructorType(func) | |
} | |
// Statics | |
const keys = Object.keys(func) | |
const statics = keys.reduce((obj, k) => { | |
if (isPrivateName(k)) return obj | |
return { ...obj, [k]: func[k] } | |
}, {}) | |
Object.assign(interfaceObj, statics) | |
// Prototype methods | |
if (func.prototype) { | |
const { prototype } = func | |
const protoKeys = Object.keys(prototype) | |
const methods = protoKeys.reduce((obj, k) => { | |
if (k === 'constructor') return obj | |
if (isPrivateName(k)) return obj | |
return { ...obj, [k]: prototype[k] } | |
}, {}) | |
Object.assign(interfaceObj, methods) | |
} | |
// Simple function | |
if (Object.keys(interfaceObj).length === 0) { | |
return constructorType(func) | |
} | |
return interfaceObj | |
} | |
const cache = new WeakSet() | |
const replacer = (key, value) => { | |
const isObj = typeof value === 'object' && value !== null | |
// Circular check | |
if (isObj && cache.has(value)) { | |
return '[Circular]' | |
} | |
if (key.length && isPrivateName(key)) return | |
if (typeof value === 'function') { | |
return jsonFunctionType(key, value) | |
} | |
if (isObj) { | |
cache.add(value) | |
} | |
return value | |
} | |
const json = JSON.stringify(targetObj, replacer, ' ') | |
console.log(json) | |
if (typeof window.copy === 'function') { | |
window.copy(json) | |
} | |
})(cast.framework) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment