UNPKG

openapi-gui

Version:

GUI / visual editor for creating and editing OpenApi / Swagger definitions

329 lines (326 loc) 11.9 kB
Vue.component('api-method', { props: ['method', 'index', 'maintags'], data: function() { return { visible: false, schemaEditor: undefined, cbName: undefined, expName: undefined } }, methods: { specLink: function(fragment) { return this.$root.specLink(fragment); }, markdownPreview: function() { this.$parent.$parent.markdownPreview('#'+this.descId); }, toggleBody : function() { this.visible = !this.visible; }, selectTab: function (name, $event) { $('.method-tab').removeClass('is-active'); $('.tabItem-method-'+name).addClass('is-active'); $('.method-pane').addClass('hidden'); $('.method-pane-'+name).removeClass('hidden'); $event.preventDefault(); }, addOperation : function() { this.$parent.addOperation(); }, duplicateOperation : function(method) { this.$parent.addOperation(method); }, removeOperation : function(target) { this.$parent.removeOperation(target); }, addParameter : function() { var newParam = {}; newParam.name = 'newParam'; newParam.in = 'query'; newParam.required = false; newParam.schema = {}; newParam.schema.type = 'string'; this.method.parameters.push(newParam); }, removeParameter : function(index) { this.$root.save(); this.method.parameters.splice(index,1); }, addRequestBody : function() { if (!this.method.requestBody) { var rb = {}; rb.content = { '*/*': { required: false, schema: {} } }; Vue.set(this.method,'requestBody',rb); } }, addResponse : function() { var status = 200; while (this.method.responses[status]) { status++; } var response = {}; response.description = 'Description'; Vue.set(this.method.responses, status, response); }, addMediaType : function() { var rb = this.effectiveRequestBody; if (rb && rb.content && !rb.content['change/me']) { Vue.set(rb.content,'change/me',{schema:{}}); } }, addCallback : function() { if (!this.method.callbacks) { Vue.set(this.method,'callbacks',{}); } if (!this.method.callbacks.newCallback) { Vue.set(this.method.callbacks,'newCallback',{newExpression:{}}); } }, duplicateCallback : function(cbname) { if (!this.method.callbacks.newCallback) { Vue.set(this.method.callbacks,'newCallback',clone(this.method.callbacks[cbname])); } }, removeCallback : function(cbname) { Vue.delete(this.method.callbacks,cbname); }, storeCallbackName : function(oldName) { this.cbName = oldName; }, renameCallback : function(newName) { Vue.set(this.method.callbacks,newName,this.method.callbacks[this.cbName]); Vue.delete(this.method.callbacks,this.cbName); }, addCallbackURL : function(cbname) { if (!this.method.callbacks[cbname].newExpression) { Vue.set(this.method.callbacks[cbname],'newExpression',{}); } }, duplicateExpression : function(cbname, expname) { if (!this.method.callbacks[cbname].newExpression) { Vue.set(this.method.callbacks[cbname],'newExpression',clone(this.method.callbacks[cbname][expname])); } }, removeExpression : function(cbname, expname) { Vue.delete(this.method.callbacks[cbname],expname); }, storeExpressionName : function(oldName) { this.expName = oldName; }, renameExpression : function(cbName, newName) { Vue.set(this.method.callbacks[cbName],newName,this.method.callbacks[cbName][this.expName]); Vue.delete(this.method.callbacks[cbName],this.expName); }, addExpressionOperation : function(exp) { if (!exp.get) { Vue.set(exp,'get',{parameters:[],responses:{default:{description:'Default response'}}}); } }, removeSecScheme : function(index) { this.method.security.splice(index,1); Vue.set(this.method,'security',this.method.security); } }, computed: { httpMethod : { get : function() { return this.index.toUpperCase(); }, set : function(newVal) { this.$parent.renameOperation(this.index, newVal.toLowerCase()); } }, hashUid : function() { return '#'+this._uid; }, descId : function() { return 'txtOpDesc'+this._uid; }, tagId : function() { return 'tags-input'+this._uid; }, hashTagId : function() { return '#'+this.tagId; }, vtags : { get : function() { if (!this.method.tags) Vue.set(this.method, 'tags', []); return this.method.tags; }, set : function(newVal) { this.method.tags = newVal; } }, mtags : { get: function() { var result = []; if (this.maintags) { for (var i=0;i<this.maintags.length;i++) { result.push(this.maintags[i].name); } } return result; } }, effectiveRequestBody : { get : function() { if (!this.method.requestBody) return null; if (!this.method.requestBody.$ref) return this.method.requestBody; return deref(this.method.requestBody, this.$root.container.openapi); } }, secType : { get : function() { if (!this.method.security) return 'default'; if (this.method.security && this.method.security.length === 0) return 'none'; return 'custom'; }, set : function(newVal) { if (newVal == 'default') { Vue.delete(this.method, 'security'); } else if (newVal == 'none') { Vue.set(this.method, 'security', []); } else { var newSec = clone(this.$root.container.openapi.security); if (!newSec || newSec.length === 0) { newSec = []; for (s in this.$root.container.openapi.components.securitySchemes) { var scheme = this.$root.container.openapi.components.securitySchemes[s]; var scopes = []; if (scheme.type === 'oauth2') { for (var f in scheme.flows) { var flow = scheme.flows[f]; if (flow.scopes) { for (sc in flow.scopes) { if (scopes.indexOf(s) < 0) scopes.push(sc); } } } } var entry = {}; entry[s] = scopes; newSec.push(entry); } } Vue.set(this.method, 'security', newSec); } } } }, beforeUpdate : function() { if (!this.method.externalDocs) { Vue.set(this.method, 'externalDocs', {}); } }, beforeMount : this.beforeUpdate, template: '#template-method' }); Vue.component('api-response', { props: ["response", "status", "method"], computed: { statusCode: { get: function () { return this.status; }, set: function (newVal) { this.$parent.renameResponse(this.status, newVal); } } }, methods: { addResponse: function () { this.$parent.addResponse(); }, removeResponse: function () { this.$root.save(); Vue.delete(this.method.responses, this.status); if (Object.keys(this.method.responses).length==0) { Vue.set(this.method.responses,'default',{description:'Default response'}); } }, addMediaType: function() { if (!this.response.content['change/me']) { Vue.set(this.response.content,'change/me',{schema:{}}); } }, renameMediaType: function(oldName, newName) { Vue.set(this.response.content, newName, this.response.content[oldName]); Vue.delete(this.response.content, oldName); } }, data: function () { return {} } }); Vue.component('api-mediatype', { props: ["content", "mediatype", "container"], computed: { mediaTypeName: { get: function () { return this.mediatype; }, set: function (newVal) { this.$parent.renameMediaType(this.mediatype, newVal); } }, schemaTooltip : { get : function() { // TODO for a $ref'd requestBody, $ref'd schemas may appear inline - set depth on deref? if (!this.content.schema || !this.content.schema.$ref) { return 'Edit inline schema'; } else { var schemaName = this.content.schema.$ref.replace('#/components/schemas/',''); return 'Edit shared schema ('+schemaName+')'; } } } }, methods: { addMediaType: function () { this.$parent.addMediaType(); }, duplicateMediaType: function() { if (!this.container.content['change/me']) { var newContent = clone(this.content); Vue.set(this.container.content,'change/me',newContent); } }, editMediaType: function (mediatype) { var initial = deref(this.container.content[mediatype].schema,this.$root.container.openapi); var editorOptions = {}; var element = document.getElementById('schemaContainer'); try { this.schemaEditor = new JSONEditor(element, editorOptions); this.schemaEditor.set(initial); this.schemaEditor.expandAll(); schemaEditorClose = function() { this.schemaEditor.destroy(); $('#schemaModal').removeClass('is-active'); }.bind(this); schemaEditorSave = function() { // TODO saving back to shared schema this.container.content[mediatype].schema = this.schemaEditor.get(); schemaEditorClose(); }.bind(this); $('#schemaModal').addClass('is-active'); } catch (ex) { this.$parent.$parent.showAlert('The editor could not be instantiated (circular schemas are not yet supported): '+ex.message); } }, removeMediaType: function () { this.$root.save(); Vue.delete(this.container.content, this.mediatype); if (Object.keys(this.container.content).length==0) { Vue.set(this.container.content,'application/json',{schema:{}}); } } }, data: function () { return {} } });