Added Swagger

This commit is contained in:
2020-06-10 08:25:21 +02:00
parent 5c6f37eaf7
commit af76cbca87
257 changed files with 48861 additions and 12 deletions
@@ -0,0 +1,15 @@
// Enable Ace editor autocompletions
export const enableAutocompletions = ({editor}) => () => {
editor.setOptions({
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true
})
}
// Add completers. Just override this method. And concat on your completer(s)
// see: https://github.com/ajaxorg/ace/blob/master/lib/ace/autocomplete.js
// eg: return ori(...args).concat({ getCompletions() {...}})
export const addAutosuggestionCompleters = () => () => {
return []
}
@@ -0,0 +1,73 @@
export function getPathForPosition({ pos: originalPos, prefix, editorValue, AST }) {
var pos = Object.assign({}, originalPos)
var lines = editorValue.split(/\r\n|\r|\n/)
var previousLine = lines[pos.row - 1] || ""
var currentLine = lines[pos.row]
var nextLine = lines[pos.row + 1] || ""
var prepared = false
// we're always at the document root when there's no indentation,
// so let's save some effort
if (pos.column === 1) {
return []
}
let prevLineIndent = getIndent(previousLine).length
let currLineIndent = getIndent(currentLine).length
const isCurrentLineEmpty = currentLine.replace(prefix, "").trim() === ""
if(
(previousLine.trim()[0] === "-" || nextLine.trim()[0] === "-")
&& currLineIndent >= prevLineIndent
&& isCurrentLineEmpty
) {
// for arrays with existing items under it, on blank lines
// example:
// myArray:
// - a: 1
// | <-- user cursor
currentLine += "- a: b" // fake array item
// pos.column += 1
prepared = true
}
// if current position is in at a free line with whitespace insert a fake
// key value pair so the generated AST in ASTManager has current position in
// editing node
if ( !prepared && isCurrentLineEmpty) {
currentLine += "a: b" // fake key value pair
pos.column += 1
prepared = true
}
if(currentLine[currentLine.length - 1] === ":") {
// Add a space if a user doesn't put one after a colon
// NOTE: this doesn't respect the "prepared" flag.
currentLine += " "
pos.column += 1
}
//if prefix is empty then add fake, empty value
if( !prepared && !prefix){
// for scalar values with no values
// i.e. "asdf: "
currentLine += "~"
}
// append inserted character in currentLine for better AST results
lines[originalPos.row] = currentLine
editorValue = lines.join("\n")
let path = AST.pathForPosition(editorValue, {
line: pos.row,
column: pos.column
})
return path
}
function getIndent(str) {
let match = str.match(/^ +/)
return match ? match[0] : ""
}
@@ -0,0 +1,46 @@
export function wrapCompleters(completers, cutoff = 100) {
let isLiveCompletionDisabled = false
let lastSpeeds = []
let isPerformant = () => lastSpeeds.every(speed => speed < cutoff)
if(cutoff === 0 || cutoff === "0") {
// never disable live autocomplete
return completers
}
return completers.map((completer, i) => {
let ori = completer.getCompletions
completer.getCompletions = function(editor, session, pos, prefix, callback) {
let startTime = Date.now()
try {
ori(editor, session, pos, prefix, (...args) => {
let msElapsed = Date.now() - startTime
lastSpeeds[i] = msElapsed
if(isLiveCompletionDisabled && isPerformant()) {
console.warn("Manual autocomplete was performant - re-enabling live autocomplete")
editor.setOptions({
enableLiveAutocompletion: true
})
isLiveCompletionDisabled = false
}
if(msElapsed > cutoff && editor.getOption("enableLiveAutocompletion")) {
console.warn("Live autocomplete is slow - disabling it")
editor.setOptions({
enableLiveAutocompletion: false
})
isLiveCompletionDisabled = true
}
callback(...args)
})
} catch(e) {
console.error("Autocompleter encountered an error")
console.error(e)
callback(null, [])
}
}
return completer
})
}
@@ -0,0 +1,36 @@
import * as actions from "./actions"
import * as fn from "./fn"
import * as specSelectors from "./spec-selectors"
import { wrapCompleters } from "./helpers"
export default function EditorAutosuggestPlugin() {
return {
fn,
statePlugins: {
spec: {
selectors: specSelectors,
},
editor: {
actions,
wrapActions: {
onLoad: (ori, sys) => (context) => {
const { editor } = context
// Any other calls for editor#onLoad
ori(context)
// Enable autosuggestions ( aka: autocompletions )
sys.editorActions.enableAutocompletions(context)
// Add completers ( for autosuggestions )
const completers = sys.editorActions.addAutosuggestionCompleters(context)
const cutoff = sys.getConfigs().liveAutocompleteCutoff
const wrappedCompleters = wrapCompleters(completers || [], cutoff)
editor.completers = wrappedCompleters
return
}
}
}
}
}
}
@@ -0,0 +1,61 @@
import { createSelector } from "reselect"
import { Set, Map } from "immutable"
import { escapeJsonPointerToken } from "../refs-util"
const SWAGGER2_REF_MAP = {
"paths": "pathitems",
"definitions": "definitions",
"schema": "definitions",
"parameters": "parameters",
"responses": "responses"
}
const OAS3_REF_MAP = {
schemas: "components/schemas", // for Schemas within Components
schema: "components/schemas", // for Schemas throughout document
parameters: "components/parameters",
requestBody: "components/requestBodies",
callbacks: "components/callbacks",
examples: "components/examples",
responses: "components/responses",
headers: "components/headers",
links: "components/links"
}
const SWAGGER2_TYPES = Set(Object.values(SWAGGER2_REF_MAP))
const OAS3_TYPES = Set(Object.values(OAS3_REF_MAP))
// Return a normalized "type" for a given path [a,b,c]
// eg: /definitions/bob => definition
// /paths/~1pets/responses/200/schema => definition ( because of schema )
export const getRefType = (state, path) => (sys) => createSelector(
() => {
for( var i=path.length-1; i>-1; i-- ) {
let tag = path[i]
if(sys.specSelectors.isOAS3 && sys.specSelectors.isOAS3()) {
if(OAS3_REF_MAP[tag]) {
return OAS3_REF_MAP[tag]
}
} else if( SWAGGER2_REF_MAP[tag] ) {
return SWAGGER2_REF_MAP[tag]
}
}
return null
})(state)
export const localRefs = (state) => (sys) => createSelector(
sys.specSelectors.spec,
sys.specSelectors.isOAS3 || (() => false),
(spec, isOAS3) => {
return (isOAS3 ? OAS3_TYPES : SWAGGER2_TYPES).toList().flatMap( type => {
return spec
.getIn(type.split("/"), Map({}))
.keySeq()
.map( name => Map({
name,
type,
$ref: `#/${type}/${escapeJsonPointerToken(name)}`,
}))
})
}
)(state)