UNPKG

@elastic.io/odata-library

Version:
130 lines (110 loc) 4.46 kB
// eslint no-restricted-syntax const { parse, convert } = require('odata2openapi'); const request = require('request-promise'); const { convertJsonSchemaToEioSchema } = require('./jsonSchemaConversionUtil'); module.exports = class CsdlConverter { constructor(csdlString) { this.csdlString = csdlString; } async build() { if (!this.csdlString) { throw new Error('Cant build schema: got no csdl string!'); } this.service = await parse(this.csdlString); this.openApiDefinition = convert(this.service.entitySets, this.service, this.service.version); return this; } async buildByMetadataUrl(metadataUrl) { if (this.csdlString) { throw new Error('Cant build schema by url: already got metadata string!'); } this.csdlString = await request(metadataUrl); return this.build(); } getResourcesList() { return this.service.entitySets .map(es => ({ name: es.name, keys: es.entityType.key })); } getEntitySet(entitySetName) { const entitySets = this.service.entitySets.filter(es => es.name === entitySetName); if (entitySets.length === 0) { throw new Error('No such name in Entity Set'); } else if (entitySets.length > 1) { throw new Error('Entity Set name not unique'); } return entitySets[0]; } getKeysForObjectType(entitySetName) { const entitySet = this.getEntitySet(entitySetName); return entitySet.entityType.key; } convertCsdlString(entitySetName) { const entitySet = this.getEntitySet(entitySetName); const fullyQualifiedName = `${entitySet.namespace}.${entitySet.entityType.name}`; return { jsonSchema: convertJsonSchemaToEioSchema(fullyQualifiedName, this.openApiDefinition.definitions), keys: entitySet.entityType.key, fieldsToWrapInQuotesInUrl: entitySet.entityType.properties .filter(p => p.wrapValueInQuotesInUrls) .map(p => p.name), }; } findMinorRef(entitySetName) { let entitySets; // eslint-disable-next-line no-restricted-syntax for (const types of [this.service.complexTypes, this.service.entitySets, this.service.entityTypes, this.service.enumTypes]) { entitySets = types.filter(es => es.name === entitySetName); if (entitySets.length !== 0) { break; } } if (entitySets.length === 0) { throw new Error('No such name in Entity Set'); } else if (entitySets.length > 1) { throw new Error('Entity Set name not unique'); } const entitySet = entitySets[0]; const fullyQualifiedName = `${entitySet.namespace}.${entitySetName}`; return convertJsonSchemaToEioSchema(fullyQualifiedName, this.openApiDefinition.definitions); } resolveMetadataRefs(jsonSchema, maxLevel) { if (!maxLevel) { maxLevel = 3; // eslint-disable-line no-param-reassign } return this.resolveMetadataRefsStep(jsonSchema, [], maxLevel, 0); } resolveMetadataRefsStep(jsonSchema, stack, maxLevel, currentLevel) { const jsonSchemaCopy = JSON.parse(JSON.stringify(jsonSchema)); if (currentLevel >= maxLevel) { return jsonSchemaCopy; } Object.keys(jsonSchema.properties) .forEach((key) => { const property = jsonSchema.properties[key]; if (property.type === 'object' && property.$ref) { const refEntityName = property.$ref.match('[a-zA-Z]+$')[0]; if (stack.indexOf(refEntityName) === -1) { stack.push(refEntityName); let schema = this.findMinorRef(refEntityName); schema = this.resolveMetadataRefsStep(schema, stack, maxLevel, currentLevel + 1); jsonSchemaCopy.properties[key].properties = schema.properties; stack.splice(stack.indexOf(refEntityName), 1); } delete jsonSchemaCopy.properties[key].$ref; } else if (property.type === 'array' && property.items.$ref) { const refEntityName = property.items.$ref.match('[a-zA-Z]+$')[0]; if (stack.indexOf(refEntityName) === -1) { stack.push(refEntityName); let schema = this.findMinorRef(refEntityName); schema = this.resolveMetadataRefsStep(schema, stack, maxLevel, currentLevel + 1); jsonSchemaCopy.properties[key].items = schema; stack.splice(stack.indexOf(refEntityName), 1); } delete jsonSchemaCopy.properties[key].items.$ref; } }); return jsonSchemaCopy; } };