ConnectionSchemaPlugin.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. Copyright (C) 2017 Cloudbase Solutions SRL
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. // @flow
  15. import LabelDictionary from '../../../utils/LabelDictionary'
  16. import Utils from '../../../utils/ObjectUtils'
  17. import type { Schema, SchemaProperties, SchemaDefinitions } from '../../../types/Schema'
  18. import type { Field } from '../../../types/Field'
  19. export const defaultSchemaToFields = (schema: SchemaProperties, schemaDefinitions?: ?SchemaDefinitions, parent?: string): any[] => {
  20. if (!schema.properties) {
  21. return []
  22. }
  23. let fields = Object.keys(schema.properties).map(fieldName => {
  24. let properties: any = schema.properties[fieldName]
  25. if (typeof properties.$ref === 'string' && schemaDefinitions) {
  26. const definitionName = properties.$ref.substr(properties.$ref.lastIndexOf('/') + 1)
  27. properties = schemaDefinitions[definitionName]
  28. return {
  29. name: fieldName,
  30. type: properties.type ? properties.type : '',
  31. properties: properties.properties ? defaultSchemaToFields(properties, null, fieldName) : [],
  32. }
  33. } else if (properties.type === 'object' && properties.properties && Object.keys(properties.properties).length) {
  34. return {
  35. name: fieldName,
  36. type: 'object',
  37. properties: defaultSchemaToFields(properties, null, fieldName),
  38. }
  39. }
  40. const name = parent ? `${parent}/${fieldName}` : fieldName
  41. LabelDictionary.pushToCache({ name, title: properties.title, description: properties.description })
  42. return {
  43. ...properties,
  44. name,
  45. required: schema.required && schema.required.find(k => k === fieldName) ? true : fieldName === 'username' || fieldName === 'password',
  46. }
  47. })
  48. return fields
  49. }
  50. export const connectionSchemaToFields = (schema: SchemaProperties) => {
  51. let fields = defaultSchemaToFields(schema)
  52. let sortPriority = { username: 1, password: 2 }
  53. fields.sort((a, b) => {
  54. if (sortPriority[a.name] && sortPriority[b.name]) {
  55. return sortPriority[a.name] - sortPriority[b.name]
  56. }
  57. if (sortPriority[a.name] || (a.required && !b.required)) {
  58. return -1
  59. }
  60. if (sortPriority[b.name] || (!a.required && b.required)) {
  61. return 1
  62. }
  63. return a.name.localeCompare(b.name)
  64. })
  65. return fields
  66. }
  67. export const generateField = (name: string, label: string, required: boolean = false, type: string = 'string', defaultValue: any = null) => {
  68. let field = {
  69. name,
  70. label,
  71. type,
  72. required,
  73. default: undefined,
  74. }
  75. if (defaultValue) {
  76. field.default = defaultValue
  77. }
  78. return field
  79. }
  80. export const fieldsToPayload = (data: { [string]: mixed }, schema: SchemaProperties) => {
  81. let info = {}
  82. Object.keys(schema.properties).forEach(fieldName => {
  83. if (data[fieldName] && typeof data[fieldName] !== 'object') {
  84. info[fieldName] = Utils.trim(fieldName, data[fieldName])
  85. } else if (typeof schema.properties[fieldName] === 'object') {
  86. // $FlowIgnore
  87. let properties = schema.properties[fieldName] && schema.properties[fieldName].properties
  88. if (properties) {
  89. Object.keys(properties).forEach(fn => {
  90. let fullFn = `${fieldName}/${fn}`
  91. if (data[fullFn] != null) {
  92. if (!info[fieldName]) {
  93. info[fieldName] = {}
  94. }
  95. info[fieldName][fn] = Utils.trim(fn, data[fullFn])
  96. }
  97. })
  98. }
  99. } else if (
  100. !data[fieldName] &&
  101. schema.required && schema.required.find(f => f === fieldName) &&
  102. schema.properties[fieldName].default
  103. ) {
  104. info[fieldName] = schema.properties[fieldName].default
  105. }
  106. })
  107. return info
  108. }
  109. export default class ConnectionSchemaParser {
  110. static parseSchemaToFields(schema: Schema): Field[] {
  111. let fields = connectionSchemaToFields(schema.oneOf[0])
  112. fields = [
  113. generateField('name', 'Endpoint Name', true),
  114. generateField('description', 'Endpoint Description'),
  115. ...fields,
  116. ]
  117. return fields
  118. }
  119. static parseFieldsToPayload(data: { [string]: mixed }, schema: any) {
  120. let payload = {}
  121. payload.name = data.name
  122. payload.description = data.description
  123. let schemaRoot = schema.oneOf ? schema.oneOf[0] : schema
  124. payload.connection_info = fieldsToPayload(data, schemaRoot)
  125. if (data.secret_ref) {
  126. payload.connection_info.secret_ref = data.secret_ref
  127. }
  128. return payload
  129. }
  130. }