mirror of
https://github.com/postmanlabs/openapi-to-postman.git
synced 2022-11-29 22:05:00 +03:00
added support for: date-time, date, float, double, and verification for byte, binary and password
350 lines
10 KiB
JavaScript
350 lines
10 KiB
JavaScript
/**
|
|
* This file contains util functions that are common between versions
|
|
*/
|
|
|
|
const parse = require('../parse.js'),
|
|
_ = require('lodash'),
|
|
typesMap = {
|
|
integer: {
|
|
int32: '<integer>',
|
|
int64: '<long>'
|
|
},
|
|
number: {
|
|
float: '<float>',
|
|
double: '<double>'
|
|
},
|
|
string: {
|
|
byte: '<byte>',
|
|
binary: '<binary>',
|
|
date: '<date>',
|
|
'date-time': '<dateTime>',
|
|
password: '<password>'
|
|
},
|
|
boolean: '<boolean>',
|
|
array: '<array>',
|
|
object: '<object>'
|
|
},
|
|
|
|
/* eslint-disable arrow-body-style */
|
|
schemaTypeToJsValidator = {
|
|
'string': (d) => typeof d === 'string',
|
|
'number': (d) => !isNaN(d),
|
|
'integer': (d) => !isNaN(d) && Number.isInteger(Number(d)),
|
|
'boolean': (d) => _.isBoolean(d) || d === 'true' || d === 'false',
|
|
'array': (d) => Array.isArray(d),
|
|
'object': (d) => typeof d === 'object' && !Array.isArray(d)
|
|
};
|
|
|
|
/**
|
|
* Remove the # character from the beginning of a schema path
|
|
* @param {string} schemaPath - a defined schemaPath
|
|
* @returns {string} - the schema path with # removed
|
|
*/
|
|
function removeSharpAndSlashFromFirstPosition(schemaPath) {
|
|
return schemaPath[0] === '#' ? schemaPath.slice(2) : schemaPath;
|
|
}
|
|
|
|
/**
|
|
* Remove the defined word from the last position of a schema path
|
|
* @param {string} schemaPath - a defined schemaPath
|
|
* @param {string} word - word to remove
|
|
* @returns {string} - the schema path with type removed
|
|
*/
|
|
function removeWordFromLastPosition(schemaPath, word) {
|
|
let splittedDataPath = schemaPath.split('/');
|
|
if (splittedDataPath[splittedDataPath.length - 1] === word) {
|
|
splittedDataPath.splice(-1);
|
|
}
|
|
return splittedDataPath.join('/');
|
|
}
|
|
|
|
/**
|
|
* Checks if value is the representation of its type like:
|
|
* "<integer>"
|
|
*
|
|
* @param {string} value - Value to check for
|
|
* @param {string} type - The type in the schemna
|
|
* @returns {Boolean} the value is the representation of its type
|
|
*/
|
|
function compareType(value, type) {
|
|
return value === '<' + type + '>';
|
|
}
|
|
|
|
/**
|
|
* Checks if value is the representation of its type like:
|
|
* "<integer>"
|
|
* Works in array types
|
|
* @param {string} value - Value to check for
|
|
* @param {*} types - The types in the schemna
|
|
* @returns {Boolean} the value is the representation of its type
|
|
*/
|
|
function isTypeValueArrayCheck(value, types) {
|
|
return types.find((type) => {
|
|
return compareType(value, type);
|
|
}) !== undefined;
|
|
}
|
|
|
|
/**
|
|
* Checks if value is the representation of its type like:
|
|
* "<integer>"
|
|
* Works in array types
|
|
* @param {string} value - Value to check for
|
|
* @param {*} types - The types in the schemna
|
|
* @returns {Boolean} the value is the representation of its type
|
|
*/
|
|
function checkValueOnlyTypes(value, types) {
|
|
return Array.isArray(types) ? isTypeValueArrayCheck(value, types) : compareType(value, types);
|
|
}
|
|
|
|
/**
|
|
* Checks if value is postman variable or not
|
|
*
|
|
* @param {string} type - type to look for
|
|
* @param {string} format - format from schema
|
|
* @returns {Boolean} postman variable or not
|
|
*/
|
|
function getDefaultFromTypeAndFormat(type, format) {
|
|
return typesMap[type][format];
|
|
}
|
|
|
|
|
|
/**
|
|
* Checks if value is the representation of its type like:
|
|
* "<integer>"
|
|
* Works in array types
|
|
* @param {string} value - Value to check for
|
|
* @param {*} types - The types in the schema
|
|
* @param {*} format - format from the schema
|
|
* @returns {Boolean} the value is the representation of its type
|
|
*/
|
|
function checkValueTypesAndFormat(value, types, format) {
|
|
let typesNotInMapp = [],
|
|
typesArray = Array.isArray(types) ? types : [types],
|
|
found = typesArray.find((type) => {
|
|
let defaultValue;
|
|
if (typesMap.hasOwnProperty(type)) {
|
|
defaultValue = getDefaultFromTypeAndFormat(type, format);
|
|
|
|
// in case the format is a custom format (email, hostname etc.)
|
|
// https://swagger.io/docs/specification/data-models/data-types/#string
|
|
if (!defaultValue && format) {
|
|
defaultValue = '<' + format + '>';
|
|
}
|
|
}
|
|
else {
|
|
typesNotInMapp.push(type);
|
|
}
|
|
return defaultValue === value;
|
|
});
|
|
|
|
if (found) {
|
|
return true;
|
|
}
|
|
|
|
found = typesNotInMapp.find((type) => {
|
|
let defaultValue;
|
|
defaultValue = '<' + type + (format ? ('-' + format) : '') + '>';
|
|
return defaultValue === value;
|
|
});
|
|
|
|
return found !== undefined;
|
|
}
|
|
|
|
/**
|
|
* Checks if value is equal to the defined default
|
|
* Works in array types
|
|
* @param {string} value - Value to check for
|
|
* @param {*} definedDefault - The defined default value of the schema
|
|
* @returns {Boolean} wheter value is equal to the defined or not
|
|
*/
|
|
function checkValueEqualsDefault(value, definedDefault) {
|
|
return value === definedDefault;
|
|
}
|
|
|
|
/**
|
|
* Checks if value is the representation of its type like:
|
|
* "<integer>"
|
|
* Works in array types
|
|
* @param {string} value - Value to check for
|
|
* @param {*} schema - The schema portion used in validation
|
|
* @returns {Boolean} the value is the representation of its type
|
|
*/
|
|
function isTypeValue(value, schema) {
|
|
if (schema.hasOwnProperty('type') && schema.hasOwnProperty('default')) {
|
|
const isDefault = checkValueEqualsDefault(value, schema.default);
|
|
if (isDefault) {
|
|
return true;
|
|
}
|
|
}
|
|
if (schema.hasOwnProperty('type') && !schema.hasOwnProperty('format')) {
|
|
return checkValueOnlyTypes(value, schema.type);
|
|
}
|
|
if (schema.hasOwnProperty('type') && schema.hasOwnProperty('format')) {
|
|
return checkValueTypesAndFormat(value, schema.type, schema.format);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks if value is correcta according to schema
|
|
* If the value should be numeric, it tries to convert and then validate
|
|
* also validates if the value is a correct representation in the form of
|
|
* <long> or <integer> etc for integers format 32 or format 64
|
|
* @param {string} value - Value to check for
|
|
* @param {*} schema - The schema portion used in validation
|
|
* @returns {Boolean} the value is the representation of its type
|
|
*/
|
|
function checkIsCorrectType(value, schema) {
|
|
if (schema.hasOwnProperty('type') &&
|
|
typeof schemaTypeToJsValidator[schema.type] === 'function') {
|
|
const isCorrectType = schemaTypeToJsValidator[schema.type](value);
|
|
if (isCorrectType) {
|
|
return true;
|
|
}
|
|
}
|
|
return isTypeValue(value, schema);
|
|
}
|
|
|
|
module.exports = {
|
|
|
|
/**
|
|
* Parses an OAS string/object as a YAML or JSON
|
|
* @param {YAML/JSON} openApiSpec - The OAS 3.x specification specified in either YAML or JSON
|
|
* @param {object} inputValidation - Concrete validator according to version
|
|
* @param {Object} options computed process options
|
|
* @returns {Object} - Contains the parsed JSON-version of the OAS spec, or an error
|
|
* @no-unit-test
|
|
*/
|
|
parseSpec: function (openApiSpec, inputValidation, options) {
|
|
var openApiObj = openApiSpec,
|
|
obj,
|
|
rootValidation;
|
|
|
|
// If the open api specification is a string could be YAML or JSON
|
|
if (typeof openApiSpec === 'string') {
|
|
obj = parse.getOasObject(openApiSpec);
|
|
if (obj.result) {
|
|
openApiObj = obj.oasObject;
|
|
}
|
|
else {
|
|
return obj;
|
|
}
|
|
}
|
|
|
|
// spec is a valid JSON object at this point
|
|
|
|
// Validate the root level object for semantics
|
|
rootValidation = inputValidation.validateSpec(openApiObj, options);
|
|
if (!rootValidation.result) {
|
|
return {
|
|
result: false,
|
|
reason: rootValidation.reason
|
|
};
|
|
}
|
|
|
|
// Valid openapi root object
|
|
return {
|
|
result: true,
|
|
openapi: rootValidation.openapi
|
|
};
|
|
},
|
|
|
|
formatDataPath: function(dataPath) {
|
|
let initialDotIfExist = dataPath[0] === '/' ? '.' : '',
|
|
splittedDataPath = dataPath.split('/'),
|
|
isANumber = (value) => {
|
|
return !isNaN(value);
|
|
},
|
|
formattedElements = splittedDataPath.map((element, index) => {
|
|
if (element !== '' && isANumber(element)) {
|
|
return `[${element}]`;
|
|
}
|
|
if (element === '' || element[0] === '.') {
|
|
return element;
|
|
}
|
|
if (index === 0 && !initialDotIfExist) {
|
|
return `${element}`;
|
|
}
|
|
return `.${element}`;
|
|
}),
|
|
formattedDataPath = formattedElements.join('');
|
|
|
|
return `${formattedDataPath}`;
|
|
},
|
|
|
|
handleExclusiveMaximum: function(schema, max) {
|
|
max = schema.hasOwnProperty('maximum') ?
|
|
schema.maximum :
|
|
max;
|
|
if (schema.hasOwnProperty('exclusiveMaximum')) {
|
|
if (typeof schema.exclusiveMaximum === 'boolean') {
|
|
return schema.multipleOf ?
|
|
max - schema.multipleOf :
|
|
max - 1;
|
|
}
|
|
else if (typeof schema.exclusiveMaximum === 'number') {
|
|
return schema.multipleOf ?
|
|
schema.exclusiveMaximum - schema.multipleOf :
|
|
schema.exclusiveMaximum - 1;
|
|
}
|
|
}
|
|
return max;
|
|
},
|
|
|
|
handleExclusiveMinimum: function(schema, min) {
|
|
min = schema.hasOwnProperty('minimum') ?
|
|
schema.minimum :
|
|
min;
|
|
if (schema.hasOwnProperty('exclusiveMinimum')) {
|
|
if (typeof schema.exclusiveMinimum === 'boolean') {
|
|
return schema.multipleOf ?
|
|
min + schema.multipleOf :
|
|
min + 1;
|
|
}
|
|
else if (typeof schema.exclusiveMinimum === 'number') {
|
|
return schema.multipleOf ?
|
|
schema.exclusiveMinimum + schema.multipleOf :
|
|
schema.exclusiveMinimum + 1;
|
|
}
|
|
}
|
|
return min;
|
|
},
|
|
|
|
/**
|
|
* Removes initial "#/" from a schema path and the last "/type" segment
|
|
* @param {string} schemaPath - The OAS 3.x specification specified in either YAML or JSON
|
|
* @returns {string} - The schemaPath with initial #/ and last "/type" removed
|
|
*/
|
|
formatSchemaPathFromAJVErrorToConvertToDataPath: function (schemaPath) {
|
|
return removeWordFromLastPosition(removeWordFromLastPosition(removeSharpAndSlashFromFirstPosition(schemaPath),
|
|
'type'), 'format');
|
|
},
|
|
|
|
typesMap,
|
|
|
|
/**
|
|
* Checks if value is the representation of its type like:
|
|
* "<integer>"
|
|
* Works in array types
|
|
* @param {string} value - Value to check for
|
|
* @param {*} schema - The schema portion used in validation
|
|
* @returns {Boolean} the value is the representation of its type
|
|
*/
|
|
isTypeValue,
|
|
|
|
/**
|
|
* Checks if value is correcta according to schema
|
|
* If the value should be numeric, it tries to convert and then validate
|
|
* also validates if the value is a correct representation in the form of
|
|
* <long> or <integer> etc for integers format 32 or format 64
|
|
* @param {string} value - Value to check for
|
|
* @param {*} schema - The schema portion used in validation
|
|
* @returns {Boolean} the value is the representation of its type
|
|
*/
|
|
checkIsCorrectType,
|
|
|
|
|
|
isKnownType: function(schema) {
|
|
return typeof schemaTypeToJsValidator[schema.type] === 'function';
|
|
}
|
|
};
|