Skip to content

Instantly share code, notes, and snippets.

@TianyiLi
Created August 11, 2020 09:48
Show Gist options
  • Save TianyiLi/e339fd8d5898b38d866eab74c4f00036 to your computer and use it in GitHub Desktop.
Save TianyiLi/e339fd8d5898b38d866eab74c4f00036 to your computer and use it in GitHub Desktop.
apidocjs generate typescript definition token
// ==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();
}
@TianyiLi
Copy link
Author

Change @match url to your apidoc serve path

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment