Created
August 11, 2020 09:48
-
-
Save TianyiLi/e339fd8d5898b38d866eab74c4f00036 to your computer and use it in GitHub Desktop.
apidocjs generate typescript definition token
This file contains 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
// ==UserScript== | |
// @name apidoc json to typescript definition | |
// @namespace Violentmonkey Scripts | |
// @match https://t.onramplab.com/docs* | |
// @grant none | |
// @version 1.01 | |
// @author [email protected] | |
// @description apidoc json generate to tsd | |
// ==/UserScript== | |
{ | |
let alertInfo = window.alert || console.warn | |
function copyJs(text, callback) { | |
var fakeEle = document.createElement('textarea') | |
// Place in top-left corner of screen regardless of scroll position. | |
fakeEle.style.position = 'fixed' | |
fakeEle.style.top = 0 | |
fakeEle.style.left = 0 | |
// Ensure it has a small width and height. Setting to 1px / 1em | |
// doesn't work as this gives a negative w/h on some browsers. | |
fakeEle.style.width = '1px' | |
fakeEle.style.height = '1px' | |
// We don't need padding, reducing the size if it does flash render. | |
fakeEle.style.padding = 0 | |
// Clean up any borders. | |
fakeEle.style.border = 'none' | |
fakeEle.style.outline = 'none' | |
fakeEle.style.boxShadow = 'none' | |
// Avoid flash of white box if rendered for any reason. | |
fakeEle.style.background = 'transparent' | |
// Text to copy | |
fakeEle.value = text | |
document.body.appendChild(fakeEle) | |
fakeEle.select() | |
var error = null | |
try { | |
var successful = document.execCommand('copy') | |
error = successful ? false : true | |
} catch (err) { | |
console.warn('Unable to copy.') | |
error = true | |
} | |
// Clean up | |
document.body.removeChild(fakeEle) | |
if (error) callback(error) | |
return !error | |
} | |
const NodeCal = (nodes = {}) => | |
function todo(prev, curr) { | |
if (Array.isArray(nodes[curr])) { | |
if (!nodes[curr].length) { | |
prev[curr] = 'never[]' | |
return prev | |
} | |
if (nodes[curr][0] instanceof Object) { | |
prev[curr] = [ | |
Object.keys(nodes[curr][0]).reduce(NodeCal(nodes[curr][0]), {}), | |
] | |
return prev | |
} | |
prev[curr] = [nodes[curr][0] === null ? null : typeof nodes[curr][0]] | |
return prev | |
} else if (nodes[curr] instanceof Object) { | |
prev[curr] = Object.keys(nodes[curr]).reduce(NodeCal(nodes[curr]), {}) | |
return prev | |
} | |
prev[curr] = nodes[curr] === null ? null : typeof nodes[curr] | |
return prev | |
} | |
function nodeTransform(jsonStr = '') { | |
jsonStr = jsonStr.replace(/(\:null)/g, ':null;') | |
const syntaxStack = [] | |
const spaceLength = () => { | |
return syntaxStack.filter((ele) => ele === '}').length | |
} | |
const closeStackMatch = { | |
'{': '}', | |
'[': ']', | |
} | |
const lastRowStack = [] | |
const whiteSpace = ' '.repeat(2) | |
const newLine = '\n' | |
let newContent = '' | |
for (const charIndex in jsonStr) { | |
const char = jsonStr[charIndex] | |
const previousCharIsSemi = newContent[newContent.length - 1] === ';' | |
if (closeStackMatch[char]) { | |
syntaxStack.push(closeStackMatch[char]) | |
console.log(syntaxStack.length) | |
if (char === '{') | |
newContent = `${newContent}${char}${newLine}${whiteSpace.repeat( | |
spaceLength() | |
)}` | |
continue | |
} | |
if (syntaxStack[syntaxStack.length - 1] === char) { | |
const _tmp = syntaxStack.pop() | |
if (_tmp === ']') { | |
newContent = `${newContent}[]` | |
continue | |
} | |
if (_tmp === '}') { | |
newContent = `${newContent}${ | |
previousCharIsSemi ? '' : ';' | |
}${newLine}${whiteSpace.repeat(spaceLength())}}` | |
continue | |
} | |
} | |
if (char === ',') { | |
newContent = `${newContent}${ | |
previousCharIsSemi ? '' : ';' | |
}${newLine}${whiteSpace.repeat(spaceLength())}` | |
continue | |
} | |
if (char === ':') { | |
newContent = `${newContent}: ` | |
continue | |
} | |
newContent = `${newContent}${char}` | |
} | |
return newContent.replace(/"/g, '') | |
} | |
function appendCopy(dom) { | |
const text = dom.innerText | |
try { | |
const nodes = eval(`(${text})`) | |
const list = Object.keys(nodes).reduce(NodeCal(nodes), {}) | |
console.log(JSON.stringify(list)) | |
const afterCal = 'interface sample ' + nodeTransform(JSON.stringify(list)) | |
console.log(afterCal) | |
return afterCal | |
} catch (error) { | |
console.log(error) | |
alertInfo('Transform Failed!') | |
} | |
} | |
function initialize() { | |
if (!document.querySelectorAll('[data-type="json"]').length) { | |
setTimeout(initialize, 500) | |
return | |
} | |
document.querySelectorAll('[data-type="json"]').forEach((ele) => { | |
const btn = document.createElement('button') | |
btn.classList.add('btn', 'btn-primary') | |
btn.innerText = 'Copy to tsd interface' | |
btn.addEventListener('click', () => { | |
const text = appendCopy(ele.querySelector('code')) | |
const state = copyJs(text) | |
if (state) alertInfo('Copy as typescript definition') | |
}) | |
ele.appendChild(btn) | |
}) | |
} | |
initialize(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Change @match url to your apidoc serve path