diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7bcb638c1..2f705f358 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,21 @@
## [Unreleased]
+## [v4.13.0] - 2023-05-24
+
+### Added
+
+- Added support for generating request and response bodies in correct XML format from mentioned examples.
+- Added support for validation of specifications in case of errors to report User input errors correctly.
+
+### Fixed
+
+- Fixed issue where conversion was stuck for certain schemas with pattern.
+- Fixed an issue where definition validation was not considering multiple white space characters.
+- Fixed issue [#708](https://github.com/postmanlabs/openapi-to-postman/issues/708) where if string is defined for required field, conversion was failing.
+- Fixed issue where for certain path segments, collection generation failed.
+- Fixed TypeError occurring while checking typeof bodyContent in getXmlVersionContent.
+
## [v4.12.0] - 2023-05-04
### Added
@@ -547,7 +562,9 @@ Newer releases follow the [Keep a Changelog](https://keepachangelog.com/en/1.0.0
- Base release
-[Unreleased]: https://github.com/postmanlabs/openapi-to-postman/compare/v4.12.0...HEAD
+[Unreleased]: https://github.com/postmanlabs/openapi-to-postman/compare/v4.13.0...HEAD
+
+[v4.13.0]: https://github.com/postmanlabs/openapi-to-postman/compare/v4.12.0...v4.13.0
[v4.12.0]: https://github.com/postmanlabs/openapi-to-postman/compare/v4.11.0...v4.12.0
diff --git a/assets/json-schema-faker.js b/assets/json-schema-faker.js
index 14ab0bfbe..9650a59f6 100644
--- a/assets/json-schema-faker.js
+++ b/assets/json-schema-faker.js
@@ -23846,8 +23846,10 @@ function extend() {
/**
* CHANGE: This Makes sure that we're not adding extra spaces in generated value,
* As such behaviour generates invalid data when pattern is mentioned.
+ *
+ * To avoid infinite loop, make sure we keep adding spaces in cases where value is empty string
*/
- value += (schema.pattern ? '' : ' ') + value;
+ value += ((schema.pattern && value.length !== 0) ? '' : ' ') + value;
}
if (value.length > max) {
value = value.substr(0, max);
@@ -24256,7 +24258,7 @@ function extend() {
const properties = value.properties || {};
const patternProperties = value.patternProperties || {};
- const requiredProperties = typeof value.required === 'boolean' ? [] : (value.required || []).slice();
+ const requiredProperties = (!Array.isArray(value.required)) ? [] : (value.required || []).slice();
const allowsAdditional = value.additionalProperties !== false;
const propertyKeys = Object.keys(properties);
diff --git a/assets/openapi3Schema.json b/assets/openapi3Schema.json
new file mode 100644
index 000000000..387e2f905
--- /dev/null
+++ b/assets/openapi3Schema.json
@@ -0,0 +1,1665 @@
+{
+ "id": "https://spec.openapis.org/oas/3.0/schema/2021-09-28",
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "Validation schema for OpenAPI Specification 3.0.X.",
+ "type": "object",
+ "required": [
+ "openapi",
+ "info",
+ "paths"
+ ],
+ "properties": {
+ "openapi": {
+ "type": "string",
+ "pattern": "^3\\.0\\.\\d(-.+)?$"
+ },
+ "info": {
+ "$ref": "#/definitions/Info"
+ },
+ "externalDocs": {
+ "$ref": "#/definitions/ExternalDocumentation"
+ },
+ "servers": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/Server"
+ }
+ },
+ "security": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/SecurityRequirement"
+ }
+ },
+ "tags": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/Tag"
+ },
+ "uniqueItems": true
+ },
+ "paths": {
+ "$ref": "#/definitions/Paths"
+ },
+ "components": {
+ "$ref": "#/definitions/Components"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true,
+ "definitions": {
+ "Reference": {
+ "type": "object",
+ "required": [
+ "$ref"
+ ],
+ "patternProperties": {
+ "^\\$ref$": {
+ "type": "string",
+ "format": "uri-reference"
+ }
+ }
+ },
+ "Info": {
+ "type": "object",
+ "required": [
+ "title",
+ "version"
+ ],
+ "properties": {
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "termsOfService": {
+ "type": "string",
+ "format": "uri-reference"
+ },
+ "contact": {
+ "$ref": "#/definitions/Contact"
+ },
+ "license": {
+ "$ref": "#/definitions/License"
+ },
+ "version": {
+ "type": "string"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "Contact": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string",
+ "format": "uri-reference"
+ },
+ "email": {
+ "type": "string",
+ "format": "email"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "License": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string",
+ "format": "uri-reference"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "Server": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "url": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "variables": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/definitions/ServerVariable"
+ }
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "ServerVariable": {
+ "type": "object",
+ "required": [
+ "default"
+ ],
+ "properties": {
+ "enum": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "default": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "Components": {
+ "type": "object",
+ "properties": {
+ "schemas": {
+ "type": "object",
+ "patternProperties": {
+ "^[a-zA-Z0-9\\.\\-_]+$": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Schema"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ }
+ }
+ },
+ "responses": {
+ "type": "object",
+ "patternProperties": {
+ "^[a-zA-Z0-9\\.\\-_]+$": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Reference"
+ },
+ {
+ "$ref": "#/definitions/Response"
+ }
+ ]
+ }
+ }
+ },
+ "parameters": {
+ "type": "object",
+ "patternProperties": {
+ "^[a-zA-Z0-9\\.\\-_]+$": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Reference"
+ },
+ {
+ "$ref": "#/definitions/Parameter"
+ }
+ ]
+ }
+ }
+ },
+ "examples": {
+ "type": "object",
+ "patternProperties": {
+ "^[a-zA-Z0-9\\.\\-_]+$": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Reference"
+ },
+ {
+ "$ref": "#/definitions/Example"
+ }
+ ]
+ }
+ }
+ },
+ "requestBodies": {
+ "type": "object",
+ "patternProperties": {
+ "^[a-zA-Z0-9\\.\\-_]+$": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Reference"
+ },
+ {
+ "$ref": "#/definitions/RequestBody"
+ }
+ ]
+ }
+ }
+ },
+ "headers": {
+ "type": "object",
+ "patternProperties": {
+ "^[a-zA-Z0-9\\.\\-_]+$": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Reference"
+ },
+ {
+ "$ref": "#/definitions/Header"
+ }
+ ]
+ }
+ }
+ },
+ "securitySchemes": {
+ "type": "object",
+ "patternProperties": {
+ "^[a-zA-Z0-9\\.\\-_]+$": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Reference"
+ },
+ {
+ "$ref": "#/definitions/SecurityScheme"
+ }
+ ]
+ }
+ }
+ },
+ "links": {
+ "type": "object",
+ "patternProperties": {
+ "^[a-zA-Z0-9\\.\\-_]+$": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Reference"
+ },
+ {
+ "$ref": "#/definitions/Link"
+ }
+ ]
+ }
+ }
+ },
+ "callbacks": {
+ "type": "object",
+ "patternProperties": {
+ "^[a-zA-Z0-9\\.\\-_]+$": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Reference"
+ },
+ {
+ "$ref": "#/definitions/Callback"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "Schema": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string"
+ },
+ "multipleOf": {
+ "type": "number",
+ "minimum": 0,
+ "exclusiveMinimum": true
+ },
+ "maximum": {
+ "type": "number"
+ },
+ "exclusiveMaximum": {
+ "type": "boolean",
+ "default": false
+ },
+ "minimum": {
+ "type": "number"
+ },
+ "exclusiveMinimum": {
+ "type": "boolean",
+ "default": false
+ },
+ "maxLength": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "minLength": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "pattern": {
+ "type": "string",
+ "format": "regex"
+ },
+ "maxItems": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "minItems": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "uniqueItems": {
+ "type": "boolean",
+ "default": false
+ },
+ "maxProperties": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "minProperties": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "required": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "minItems": 1,
+ "uniqueItems": true
+ },
+ "enum": {
+ "type": "array",
+ "items": {
+ },
+ "minItems": 1,
+ "uniqueItems": false
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "array",
+ "boolean",
+ "integer",
+ "number",
+ "object",
+ "string"
+ ]
+ },
+ "not": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Schema"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ },
+ "allOf": {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Schema"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ }
+ },
+ "oneOf": {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Schema"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ }
+ },
+ "anyOf": {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Schema"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ }
+ },
+ "items": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Schema"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ },
+ "properties": {
+ "type": "object",
+ "additionalProperties": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Schema"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ }
+ },
+ "additionalProperties": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Schema"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ },
+ {
+ "type": "boolean"
+ }
+ ],
+ "default": true
+ },
+ "description": {
+ "type": "string"
+ },
+ "format": {
+ "type": "string"
+ },
+ "default": {
+ },
+ "nullable": {
+ "type": "boolean",
+ "default": false
+ },
+ "discriminator": {
+ "$ref": "#/definitions/Discriminator"
+ },
+ "readOnly": {
+ "type": "boolean",
+ "default": false
+ },
+ "writeOnly": {
+ "type": "boolean",
+ "default": false
+ },
+ "example": {
+ },
+ "externalDocs": {
+ "$ref": "#/definitions/ExternalDocumentation"
+ },
+ "deprecated": {
+ "type": "boolean",
+ "default": false
+ },
+ "xml": {
+ "$ref": "#/definitions/XML"
+ },
+ "reference": {
+ "type": "string"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": false
+ },
+ "Discriminator": {
+ "type": "object",
+ "required": [
+ "propertyName"
+ ],
+ "properties": {
+ "propertyName": {
+ "type": "string"
+ },
+ "mapping": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "XML": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "namespace": {
+ "type": "string",
+ "format": "uri"
+ },
+ "prefix": {
+ "type": "string"
+ },
+ "attribute": {
+ "type": "boolean",
+ "default": false
+ },
+ "wrapped": {
+ "type": "boolean",
+ "default": false
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "Response": {
+ "type": "object",
+ "required": [
+ "description"
+ ],
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "headers": {
+ "type": "object",
+ "additionalProperties": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Header"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ }
+ },
+ "content": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/definitions/MediaType"
+ }
+ },
+ "links": {
+ "type": "object",
+ "additionalProperties": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Link"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ }
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "MediaType": {
+ "type": "object",
+ "properties": {
+ "schema": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Schema"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ },
+ "example": {
+ },
+ "examples": {
+ "type": "object",
+ "additionalProperties": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Example"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ }
+ },
+ "encoding": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/definitions/Encoding"
+ }
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true,
+ "allOf": [
+ {
+ "$ref": "#/definitions/ExampleXORExamples"
+ }
+ ]
+ },
+ "Example": {
+ "type": "object",
+ "properties": {
+ "summary": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "value": {
+ },
+ "externalValue": {
+ "type": "string",
+ "format": "uri-reference"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "Header": {
+ "type": "object",
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "required": {
+ "type": "boolean",
+ "default": false
+ },
+ "deprecated": {
+ "type": "boolean",
+ "default": false
+ },
+ "allowEmptyValue": {
+ "type": "boolean",
+ "default": false
+ },
+ "style": {
+ "type": "string",
+ "enum": [
+ "simple"
+ ],
+ "default": "simple"
+ },
+ "explode": {
+ "type": "boolean"
+ },
+ "allowReserved": {
+ "type": "boolean",
+ "default": false
+ },
+ "schema": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Schema"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ },
+ "content": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/definitions/MediaType"
+ },
+ "minProperties": 1,
+ "maxProperties": 1
+ },
+ "example": {
+ },
+ "examples": {
+ "type": "object",
+ "additionalProperties": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Example"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ }
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true,
+ "allOf": [
+ {
+ "$ref": "#/definitions/ExampleXORExamples"
+ },
+ {
+ "$ref": "#/definitions/SchemaXORContent"
+ }
+ ]
+ },
+ "Paths": {
+ "type": "object",
+ "patternProperties": {
+ "^\\/": {
+ "$ref": "#/definitions/PathItem"
+ },
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "PathItem": {
+ "type": "object",
+ "properties": {
+ "$ref": {
+ "type": "string"
+ },
+ "summary": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "servers": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/Server"
+ }
+ },
+ "parameters": {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Parameter"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ },
+ "uniqueItems": false
+ }
+ },
+ "patternProperties": {
+ "^(get|put|post|delete|options|head|patch|trace)$": {
+ "$ref": "#/definitions/Operation"
+ },
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "Operation": {
+ "type": "object",
+ "required": [
+ "responses"
+ ],
+ "properties": {
+ "tags": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "summary": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "externalDocs": {
+ "$ref": "#/definitions/ExternalDocumentation"
+ },
+ "operationId": {
+ "type": "string"
+ },
+ "parameters": {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Parameter"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ },
+ "uniqueItems": false
+ },
+ "requestBody": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/RequestBody"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ },
+ "responses": {
+ "$ref": "#/definitions/Responses"
+ },
+ "callbacks": {
+ "type": "object",
+ "additionalProperties": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Callback"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ }
+ },
+ "deprecated": {
+ "type": "boolean",
+ "default": false
+ },
+ "security": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/SecurityRequirement"
+ }
+ },
+ "servers": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/Server"
+ }
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "Responses": {
+ "type": "object",
+ "properties": {
+ "default": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Response"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ }
+ },
+ "patternProperties": {
+ "^[1-5](?:\\d{2}|XX)$": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Response"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ },
+ "^x-": {
+ }
+ },
+ "minProperties": 1,
+ "additionalProperties": true
+ },
+ "SecurityRequirement": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "Tag": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "externalDocs": {
+ "$ref": "#/definitions/ExternalDocumentation"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "ExternalDocumentation": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string",
+ "format": "uri-reference"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "ExampleXORExamples": {
+ "description": "Example and examples are mutually exclusive",
+ "not": {
+ "required": [
+ "example",
+ "examples"
+ ]
+ }
+ },
+ "SchemaXORContent": {
+ "description": "Schema and content are mutually exclusive, at least one is required",
+ "not": {
+ "required": [
+ "schema",
+ "content"
+ ]
+ },
+ "oneOf": [
+ {
+ "required": [
+ "schema"
+ ]
+ },
+ {
+ "required": [
+ "content"
+ ],
+ "description": "Some properties are not allowed if content is present",
+ "allOf": [
+ {
+ "not": {
+ "required": [
+ "style"
+ ]
+ }
+ },
+ {
+ "not": {
+ "required": [
+ "explode"
+ ]
+ }
+ },
+ {
+ "not": {
+ "required": [
+ "allowReserved"
+ ]
+ }
+ },
+ {
+ "not": {
+ "required": [
+ "example"
+ ]
+ }
+ },
+ {
+ "not": {
+ "required": [
+ "examples"
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "Parameter": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "in": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "required": {
+ "type": "boolean",
+ "default": false
+ },
+ "deprecated": {
+ "type": "boolean",
+ "default": false
+ },
+ "allowEmptyValue": {
+ "type": "boolean",
+ "default": false
+ },
+ "style": {
+ "type": "string"
+ },
+ "explode": {
+ "type": "boolean"
+ },
+ "allowReserved": {
+ "type": "boolean",
+ "default": false
+ },
+ "schema": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Schema"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ },
+ "content": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/definitions/MediaType"
+ },
+ "minProperties": 1,
+ "maxProperties": 1
+ },
+ "example": {
+ },
+ "examples": {
+ "type": "object",
+ "additionalProperties": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Example"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ }
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true,
+ "required": [
+ "name",
+ "in"
+ ],
+ "allOf": [
+ {
+ "$ref": "#/definitions/ExampleXORExamples"
+ },
+ {
+ "$ref": "#/definitions/SchemaXORContent"
+ },
+ {
+ "$ref": "#/definitions/ParameterLocation"
+ }
+ ]
+ },
+ "ParameterLocation": {
+ "description": "Parameter location",
+ "oneOf": [
+ {
+ "description": "Parameter in path",
+ "required": [
+ "required"
+ ],
+ "properties": {
+ "in": {
+ "enum": [
+ "path"
+ ]
+ },
+ "style": {
+ "enum": [
+ "matrix",
+ "label",
+ "simple"
+ ],
+ "default": "simple"
+ },
+ "required": {
+ "enum": [
+ true
+ ]
+ }
+ }
+ },
+ {
+ "description": "Parameter in query",
+ "properties": {
+ "in": {
+ "enum": [
+ "query"
+ ]
+ },
+ "style": {
+ "enum": [
+ "form",
+ "spaceDelimited",
+ "pipeDelimited",
+ "deepObject"
+ ],
+ "default": "form"
+ }
+ }
+ },
+ {
+ "description": "Parameter in header",
+ "properties": {
+ "in": {
+ "enum": [
+ "header"
+ ]
+ },
+ "style": {
+ "enum": [
+ "simple"
+ ],
+ "default": "simple"
+ }
+ }
+ },
+ {
+ "description": "Parameter in cookie",
+ "properties": {
+ "in": {
+ "enum": [
+ "cookie"
+ ]
+ },
+ "style": {
+ "enum": [
+ "form"
+ ],
+ "default": "form"
+ }
+ }
+ }
+ ]
+ },
+ "RequestBody": {
+ "type": "object",
+ "required": [
+ "content"
+ ],
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "content": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/definitions/MediaType"
+ }
+ },
+ "required": {
+ "type": "boolean",
+ "default": false
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "SecurityScheme": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/APIKeySecurityScheme"
+ },
+ {
+ "$ref": "#/definitions/HTTPSecurityScheme"
+ },
+ {
+ "$ref": "#/definitions/OAuth2SecurityScheme"
+ },
+ {
+ "$ref": "#/definitions/OpenIdConnectSecurityScheme"
+ }
+ ]
+ },
+ "APIKeySecurityScheme": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "in"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "apiKey"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "in": {
+ "type": "string",
+ "enum": [
+ "header",
+ "query",
+ "cookie"
+ ]
+ },
+ "description": {
+ "type": "string"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "HTTPSecurityScheme": {
+ "type": "object",
+ "required": [
+ "scheme",
+ "type"
+ ],
+ "properties": {
+ "scheme": {
+ "type": "string"
+ },
+ "bearerFormat": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "http"
+ ]
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true,
+ "oneOf": [
+ {
+ "description": "Bearer",
+ "properties": {
+ "scheme": {
+ "type": "string",
+ "pattern": "^[Bb][Ee][Aa][Rr][Ee][Rr]$"
+ }
+ }
+ },
+ {
+ "description": "Non Bearer",
+ "not": {
+ "required": [
+ "bearerFormat"
+ ]
+ },
+ "properties": {
+ "scheme": {
+ "not": {
+ "type": "string",
+ "pattern": "^[Bb][Ee][Aa][Rr][Ee][Rr]$"
+ }
+ }
+ }
+ }
+ ]
+ },
+ "OAuth2SecurityScheme": {
+ "type": "object",
+ "required": [
+ "type",
+ "flows"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "oauth2"
+ ]
+ },
+ "flows": {
+ "$ref": "#/definitions/OAuthFlows"
+ },
+ "description": {
+ "type": "string"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "OpenIdConnectSecurityScheme": {
+ "type": "object",
+ "required": [
+ "type",
+ "openIdConnectUrl"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "openIdConnect"
+ ]
+ },
+ "openIdConnectUrl": {
+ "type": "string",
+ "format": "uri-reference"
+ },
+ "description": {
+ "type": "string"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "OAuthFlows": {
+ "type": "object",
+ "properties": {
+ "implicit": {
+ "$ref": "#/definitions/ImplicitOAuthFlow"
+ },
+ "password": {
+ "$ref": "#/definitions/PasswordOAuthFlow"
+ },
+ "clientCredentials": {
+ "$ref": "#/definitions/ClientCredentialsFlow"
+ },
+ "authorizationCode": {
+ "$ref": "#/definitions/AuthorizationCodeOAuthFlow"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "ImplicitOAuthFlow": {
+ "type": "object",
+ "required": [
+ "authorizationUrl",
+ "scopes"
+ ],
+ "properties": {
+ "authorizationUrl": {
+ "type": "string",
+ "format": "uri-reference"
+ },
+ "refreshUrl": {
+ "type": "string",
+ "format": "uri-reference"
+ },
+ "scopes": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "PasswordOAuthFlow": {
+ "type": "object",
+ "required": [
+ "tokenUrl",
+ "scopes"
+ ],
+ "properties": {
+ "tokenUrl": {
+ "type": "string",
+ "format": "uri-reference"
+ },
+ "refreshUrl": {
+ "type": "string",
+ "format": "uri-reference"
+ },
+ "scopes": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "ClientCredentialsFlow": {
+ "type": "object",
+ "required": [
+ "tokenUrl",
+ "scopes"
+ ],
+ "properties": {
+ "tokenUrl": {
+ "type": "string",
+ "format": "uri-reference"
+ },
+ "refreshUrl": {
+ "type": "string",
+ "format": "uri-reference"
+ },
+ "scopes": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "AuthorizationCodeOAuthFlow": {
+ "type": "object",
+ "required": [
+ "authorizationUrl",
+ "tokenUrl",
+ "scopes"
+ ],
+ "properties": {
+ "authorizationUrl": {
+ "type": "string",
+ "format": "uri-reference"
+ },
+ "tokenUrl": {
+ "type": "string",
+ "format": "uri-reference"
+ },
+ "refreshUrl": {
+ "type": "string",
+ "format": "uri-reference"
+ },
+ "scopes": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true
+ },
+ "Link": {
+ "type": "object",
+ "properties": {
+ "operationId": {
+ "type": "string"
+ },
+ "operationRef": {
+ "type": "string",
+ "format": "uri-reference"
+ },
+ "parameters": {
+ "type": "object",
+ "additionalProperties": {
+ }
+ },
+ "requestBody": {
+ },
+ "description": {
+ "type": "string"
+ },
+ "server": {
+ "$ref": "#/definitions/Server"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ },
+ "additionalProperties": true,
+ "not": {
+ "description": "Operation Id and Operation Ref are mutually exclusive",
+ "required": [
+ "operationId",
+ "operationRef"
+ ]
+ }
+ },
+ "Callback": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/definitions/PathItem"
+ },
+ "patternProperties": {
+ "^x-": {
+ }
+ }
+ },
+ "Encoding": {
+ "type": "object",
+ "properties": {
+ "contentType": {
+ "type": "string"
+ },
+ "headers": {
+ "type": "object",
+ "additionalProperties": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/Header"
+ },
+ {
+ "$ref": "#/definitions/Reference"
+ }
+ ]
+ }
+ },
+ "style": {
+ "type": "string",
+ "enum": [
+ "form",
+ "spaceDelimited",
+ "pipeDelimited",
+ "deepObject"
+ ]
+ },
+ "explode": {
+ "type": "boolean"
+ },
+ "allowReserved": {
+ "type": "boolean",
+ "default": false
+ }
+ },
+ "additionalProperties": true
+ }
+ }
+ }
\ No newline at end of file
diff --git a/assets/swagger2Schema.json b/assets/swagger2Schema.json
new file mode 100644
index 000000000..92f0a4ed0
--- /dev/null
+++ b/assets/swagger2Schema.json
@@ -0,0 +1,1618 @@
+{
+ "title": "A JSON Schema for Swagger 2.0 API.",
+ "id": "http://swagger.io/v2/schema.json#",
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "type": "object",
+ "required": [
+ "swagger",
+ "info",
+ "paths"
+ ],
+ "additionalProperties": false,
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ },
+ "properties": {
+ "swagger": {
+ "type": "string",
+ "enum": [
+ "2.0"
+ ],
+ "description": "The Swagger version of this document."
+ },
+ "info": {
+ "$ref": "#/definitions/info"
+ },
+ "host": {
+ "type": "string",
+ "pattern": "^[^{}/ :\\\\]+(?::\\d+)?$",
+ "description": "The host (name or ip) of the API. Example: 'swagger.io'"
+ },
+ "basePath": {
+ "type": "string",
+ "pattern": "^/",
+ "description": "The base path to the API. Example: '/api'."
+ },
+ "schemes": {
+ "$ref": "#/definitions/schemesList"
+ },
+ "consumes": {
+ "description": "A list of MIME types accepted by the API.",
+ "allOf": [
+ {
+ "$ref": "#/definitions/mediaTypeList"
+ }
+ ]
+ },
+ "produces": {
+ "description": "A list of MIME types the API can produce.",
+ "allOf": [
+ {
+ "$ref": "#/definitions/mediaTypeList"
+ }
+ ]
+ },
+ "paths": {
+ "$ref": "#/definitions/paths"
+ },
+ "definitions": {
+ "$ref": "#/definitions/definitions"
+ },
+ "parameters": {
+ "$ref": "#/definitions/parameterDefinitions"
+ },
+ "responses": {
+ "$ref": "#/definitions/responseDefinitions"
+ },
+ "security": {
+ "$ref": "#/definitions/security"
+ },
+ "securityDefinitions": {
+ "$ref": "#/definitions/securityDefinitions"
+ },
+ "tags": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/tag"
+ },
+ "uniqueItems": true
+ },
+ "externalDocs": {
+ "$ref": "#/definitions/externalDocs"
+ }
+ },
+ "definitions": {
+ "info": {
+ "type": "object",
+ "description": "General information about the API.",
+ "required": [
+ "version",
+ "title"
+ ],
+ "additionalProperties": false,
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ },
+ "properties": {
+ "title": {
+ "type": "string",
+ "description": "A unique and precise title of the API."
+ },
+ "version": {
+ "type": "string",
+ "description": "A semantic version number of the API."
+ },
+ "description": {
+ "type": "string",
+ "description": "A longer description of the API. Should be different from the title. GitHub Flavored Markdown is allowed."
+ },
+ "termsOfService": {
+ "type": "string",
+ "description": "The terms of service for the API."
+ },
+ "contact": {
+ "$ref": "#/definitions/contact"
+ },
+ "license": {
+ "$ref": "#/definitions/license"
+ }
+ }
+ },
+ "contact": {
+ "type": "object",
+ "description": "Contact information for the owners of the API.",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The identifying name of the contact person/organization."
+ },
+ "url": {
+ "type": "string",
+ "description": "The URL pointing to the contact information.",
+ "format": "uri"
+ },
+ "email": {
+ "type": "string",
+ "description": "The email address of the contact person/organization.",
+ "format": "email"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ }
+ },
+ "license": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the license type. It's encouraged to use an OSI compatible license."
+ },
+ "url": {
+ "type": "string",
+ "description": "The URL pointing to the license.",
+ "format": "uri"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ }
+ },
+ "paths": {
+ "type": "object",
+ "description": "Relative paths to the individual endpoints. They must be relative to the 'basePath'.",
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ },
+ "^/": {
+ "$ref": "#/definitions/pathItem"
+ }
+ },
+ "additionalProperties": false
+ },
+ "definitions": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/definitions/schema"
+ },
+ "description": "One or more JSON objects describing the schemas being consumed and produced by the API."
+ },
+ "parameterDefinitions": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/definitions/parameter"
+ },
+ "description": "One or more JSON representations for parameters"
+ },
+ "responseDefinitions": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/definitions/response"
+ },
+ "description": "One or more JSON representations for responses"
+ },
+ "externalDocs": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "information about external documentation",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string",
+ "format": "uri"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ }
+ },
+ "examples": {
+ "type": "object",
+ "additionalProperties": true
+ },
+ "mimeType": {
+ "type": "string",
+ "description": "The MIME type of the HTTP message."
+ },
+ "operation": {
+ "type": "object",
+ "required": [
+ "responses"
+ ],
+ "additionalProperties": false,
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ },
+ "properties": {
+ "tags": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "uniqueItems": true
+ },
+ "summary": {
+ "type": "string",
+ "description": "A brief summary of the operation."
+ },
+ "description": {
+ "type": "string",
+ "description": "A longer description of the operation, GitHub Flavored Markdown is allowed."
+ },
+ "externalDocs": {
+ "$ref": "#/definitions/externalDocs"
+ },
+ "operationId": {
+ "type": "string",
+ "description": "A unique identifier of the operation."
+ },
+ "produces": {
+ "description": "A list of MIME types the API can produce.",
+ "allOf": [
+ {
+ "$ref": "#/definitions/mediaTypeList"
+ }
+ ]
+ },
+ "consumes": {
+ "description": "A list of MIME types the API can consume.",
+ "allOf": [
+ {
+ "$ref": "#/definitions/mediaTypeList"
+ }
+ ]
+ },
+ "parameters": {
+ "$ref": "#/definitions/parametersList"
+ },
+ "responses": {
+ "$ref": "#/definitions/responses"
+ },
+ "schemes": {
+ "$ref": "#/definitions/schemesList"
+ },
+ "deprecated": {
+ "type": "boolean",
+ "default": false
+ },
+ "security": {
+ "$ref": "#/definitions/security"
+ }
+ }
+ },
+ "pathItem": {
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ },
+ "properties": {
+ "$ref": {
+ "type": "string"
+ },
+ "get": {
+ "$ref": "#/definitions/operation"
+ },
+ "put": {
+ "$ref": "#/definitions/operation"
+ },
+ "post": {
+ "$ref": "#/definitions/operation"
+ },
+ "delete": {
+ "$ref": "#/definitions/operation"
+ },
+ "options": {
+ "$ref": "#/definitions/operation"
+ },
+ "head": {
+ "$ref": "#/definitions/operation"
+ },
+ "patch": {
+ "$ref": "#/definitions/operation"
+ },
+ "parameters": {
+ "$ref": "#/definitions/parametersList"
+ }
+ }
+ },
+ "responses": {
+ "type": "object",
+ "description": "Response objects names can either be any valid HTTP status code or 'default'.",
+ "minProperties": 1,
+ "additionalProperties": false,
+ "patternProperties": {
+ "^([0-9]{3})$|^(default)$": {
+ "$ref": "#/definitions/responseValue"
+ },
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ },
+ "not": {
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ }
+ }
+ },
+ "responseValue": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/response"
+ },
+ {
+ "$ref": "#/definitions/jsonReference"
+ }
+ ]
+ },
+ "response": {
+ "type": "object",
+ "required": [
+ "description"
+ ],
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "schema": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/schema"
+ },
+ {
+ "$ref": "#/definitions/fileSchema"
+ }
+ ]
+ },
+ "headers": {
+ "$ref": "#/definitions/headers"
+ },
+ "examples": {
+ "$ref": "#/definitions/examples"
+ }
+ },
+ "additionalProperties": false,
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ }
+ },
+ "headers": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/definitions/header"
+ }
+ },
+ "header": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "string",
+ "number",
+ "integer",
+ "boolean",
+ "array"
+ ]
+ },
+ "format": {
+ "type": "string"
+ },
+ "items": {
+ "$ref": "#/definitions/primitivesItems"
+ },
+ "collectionFormat": {
+ "$ref": "#/definitions/collectionFormat"
+ },
+ "default": {
+ "$ref": "#/definitions/default"
+ },
+ "maximum": {
+ "$ref": "#/definitions/maximum"
+ },
+ "exclusiveMaximum": {
+ "$ref": "#/definitions/exclusiveMaximum"
+ },
+ "minimum": {
+ "$ref": "#/definitions/minimum"
+ },
+ "exclusiveMinimum": {
+ "$ref": "#/definitions/exclusiveMinimum"
+ },
+ "maxLength": {
+ "$ref": "#/definitions/maxLength"
+ },
+ "minLength": {
+ "$ref": "#/definitions/minLength"
+ },
+ "pattern": {
+ "$ref": "#/definitions/pattern"
+ },
+ "maxItems": {
+ "$ref": "#/definitions/maxItems"
+ },
+ "minItems": {
+ "$ref": "#/definitions/minItems"
+ },
+ "uniqueItems": {
+ "$ref": "#/definitions/uniqueItems"
+ },
+ "enum": {
+ "$ref": "#/definitions/enum"
+ },
+ "multipleOf": {
+ "$ref": "#/definitions/multipleOf"
+ },
+ "description": {
+ "type": "string"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ }
+ },
+ "vendorExtension": {
+ "description": "Any property starting with x- is valid.",
+ "additionalProperties": true,
+ "additionalItems": true
+ },
+ "bodyParameter": {
+ "type": "object",
+ "required": [
+ "name",
+ "in",
+ "schema"
+ ],
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ },
+ "properties": {
+ "description": {
+ "type": "string",
+ "description": "A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed."
+ },
+ "name": {
+ "type": "string",
+ "description": "The name of the parameter."
+ },
+ "in": {
+ "type": "string",
+ "description": "Determines the location of the parameter.",
+ "enum": [
+ "body"
+ ]
+ },
+ "required": {
+ "type": "boolean",
+ "description": "Determines whether or not this parameter is required or optional.",
+ "default": false
+ },
+ "schema": {
+ "$ref": "#/definitions/schema"
+ }
+ },
+ "additionalProperties": false
+ },
+ "headerParameterSubSchema": {
+ "additionalProperties": false,
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ },
+ "properties": {
+ "required": {
+ "type": "boolean",
+ "description": "Determines whether or not this parameter is required or optional.",
+ "default": false
+ },
+ "in": {
+ "type": "string",
+ "description": "Determines the location of the parameter.",
+ "enum": [
+ "header"
+ ]
+ },
+ "description": {
+ "type": "string",
+ "description": "A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed."
+ },
+ "name": {
+ "type": "string",
+ "description": "The name of the parameter."
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "string",
+ "number",
+ "boolean",
+ "integer",
+ "array"
+ ]
+ },
+ "format": {
+ "type": "string"
+ },
+ "items": {
+ "$ref": "#/definitions/primitivesItems"
+ },
+ "collectionFormat": {
+ "$ref": "#/definitions/collectionFormat"
+ },
+ "default": {
+ "$ref": "#/definitions/default"
+ },
+ "maximum": {
+ "$ref": "#/definitions/maximum"
+ },
+ "exclusiveMaximum": {
+ "$ref": "#/definitions/exclusiveMaximum"
+ },
+ "minimum": {
+ "$ref": "#/definitions/minimum"
+ },
+ "exclusiveMinimum": {
+ "$ref": "#/definitions/exclusiveMinimum"
+ },
+ "maxLength": {
+ "$ref": "#/definitions/maxLength"
+ },
+ "minLength": {
+ "$ref": "#/definitions/minLength"
+ },
+ "pattern": {
+ "$ref": "#/definitions/pattern"
+ },
+ "maxItems": {
+ "$ref": "#/definitions/maxItems"
+ },
+ "minItems": {
+ "$ref": "#/definitions/minItems"
+ },
+ "uniqueItems": {
+ "$ref": "#/definitions/uniqueItems"
+ },
+ "enum": {
+ "$ref": "#/definitions/enum"
+ },
+ "multipleOf": {
+ "$ref": "#/definitions/multipleOf"
+ }
+ }
+ },
+ "queryParameterSubSchema": {
+ "additionalProperties": false,
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ },
+ "properties": {
+ "required": {
+ "type": "boolean",
+ "description": "Determines whether or not this parameter is required or optional.",
+ "default": false
+ },
+ "in": {
+ "type": "string",
+ "description": "Determines the location of the parameter.",
+ "enum": [
+ "query"
+ ]
+ },
+ "description": {
+ "type": "string",
+ "description": "A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed."
+ },
+ "name": {
+ "type": "string",
+ "description": "The name of the parameter."
+ },
+ "allowEmptyValue": {
+ "type": "boolean",
+ "default": false,
+ "description": "allows sending a parameter by name only or with an empty value."
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "string",
+ "number",
+ "boolean",
+ "integer",
+ "array"
+ ]
+ },
+ "format": {
+ "type": "string"
+ },
+ "items": {
+ "$ref": "#/definitions/primitivesItems"
+ },
+ "collectionFormat": {
+ "$ref": "#/definitions/collectionFormatWithMulti"
+ },
+ "default": {
+ "$ref": "#/definitions/default"
+ },
+ "maximum": {
+ "$ref": "#/definitions/maximum"
+ },
+ "exclusiveMaximum": {
+ "$ref": "#/definitions/exclusiveMaximum"
+ },
+ "minimum": {
+ "$ref": "#/definitions/minimum"
+ },
+ "exclusiveMinimum": {
+ "$ref": "#/definitions/exclusiveMinimum"
+ },
+ "maxLength": {
+ "$ref": "#/definitions/maxLength"
+ },
+ "minLength": {
+ "$ref": "#/definitions/minLength"
+ },
+ "pattern": {
+ "$ref": "#/definitions/pattern"
+ },
+ "maxItems": {
+ "$ref": "#/definitions/maxItems"
+ },
+ "minItems": {
+ "$ref": "#/definitions/minItems"
+ },
+ "uniqueItems": {
+ "$ref": "#/definitions/uniqueItems"
+ },
+ "enum": {
+ "$ref": "#/definitions/enum"
+ },
+ "multipleOf": {
+ "$ref": "#/definitions/multipleOf"
+ }
+ }
+ },
+ "formDataParameterSubSchema": {
+ "additionalProperties": false,
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ },
+ "properties": {
+ "required": {
+ "type": "boolean",
+ "description": "Determines whether or not this parameter is required or optional.",
+ "default": false
+ },
+ "in": {
+ "type": "string",
+ "description": "Determines the location of the parameter.",
+ "enum": [
+ "formData"
+ ]
+ },
+ "description": {
+ "type": "string",
+ "description": "A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed."
+ },
+ "name": {
+ "type": "string",
+ "description": "The name of the parameter."
+ },
+ "allowEmptyValue": {
+ "type": "boolean",
+ "default": false,
+ "description": "allows sending a parameter by name only or with an empty value."
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "string",
+ "number",
+ "boolean",
+ "integer",
+ "array",
+ "file"
+ ]
+ },
+ "format": {
+ "type": "string"
+ },
+ "items": {
+ "$ref": "#/definitions/primitivesItems"
+ },
+ "collectionFormat": {
+ "$ref": "#/definitions/collectionFormatWithMulti"
+ },
+ "default": {
+ "$ref": "#/definitions/default"
+ },
+ "maximum": {
+ "$ref": "#/definitions/maximum"
+ },
+ "exclusiveMaximum": {
+ "$ref": "#/definitions/exclusiveMaximum"
+ },
+ "minimum": {
+ "$ref": "#/definitions/minimum"
+ },
+ "exclusiveMinimum": {
+ "$ref": "#/definitions/exclusiveMinimum"
+ },
+ "maxLength": {
+ "$ref": "#/definitions/maxLength"
+ },
+ "minLength": {
+ "$ref": "#/definitions/minLength"
+ },
+ "pattern": {
+ "$ref": "#/definitions/pattern"
+ },
+ "maxItems": {
+ "$ref": "#/definitions/maxItems"
+ },
+ "minItems": {
+ "$ref": "#/definitions/minItems"
+ },
+ "uniqueItems": {
+ "$ref": "#/definitions/uniqueItems"
+ },
+ "enum": {
+ "$ref": "#/definitions/enum"
+ },
+ "multipleOf": {
+ "$ref": "#/definitions/multipleOf"
+ }
+ }
+ },
+ "pathParameterSubSchema": {
+ "additionalProperties": false,
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ },
+ "required": [
+ "required"
+ ],
+ "properties": {
+ "required": {
+ "type": "boolean",
+ "enum": [
+ true
+ ],
+ "description": "Determines whether or not this parameter is required or optional."
+ },
+ "in": {
+ "type": "string",
+ "description": "Determines the location of the parameter.",
+ "enum": [
+ "path"
+ ]
+ },
+ "description": {
+ "type": "string",
+ "description": "A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed."
+ },
+ "name": {
+ "type": "string",
+ "description": "The name of the parameter."
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "string",
+ "number",
+ "boolean",
+ "integer",
+ "array"
+ ]
+ },
+ "format": {
+ "type": "string"
+ },
+ "items": {
+ "$ref": "#/definitions/primitivesItems"
+ },
+ "collectionFormat": {
+ "$ref": "#/definitions/collectionFormat"
+ },
+ "default": {
+ "$ref": "#/definitions/default"
+ },
+ "maximum": {
+ "$ref": "#/definitions/maximum"
+ },
+ "exclusiveMaximum": {
+ "$ref": "#/definitions/exclusiveMaximum"
+ },
+ "minimum": {
+ "$ref": "#/definitions/minimum"
+ },
+ "exclusiveMinimum": {
+ "$ref": "#/definitions/exclusiveMinimum"
+ },
+ "maxLength": {
+ "$ref": "#/definitions/maxLength"
+ },
+ "minLength": {
+ "$ref": "#/definitions/minLength"
+ },
+ "pattern": {
+ "$ref": "#/definitions/pattern"
+ },
+ "maxItems": {
+ "$ref": "#/definitions/maxItems"
+ },
+ "minItems": {
+ "$ref": "#/definitions/minItems"
+ },
+ "uniqueItems": {
+ "$ref": "#/definitions/uniqueItems"
+ },
+ "enum": {
+ "$ref": "#/definitions/enum"
+ },
+ "multipleOf": {
+ "$ref": "#/definitions/multipleOf"
+ }
+ }
+ },
+ "nonBodyParameter": {
+ "type": "object",
+ "required": [
+ "name",
+ "in",
+ "type"
+ ],
+ "oneOf": [
+ {
+ "$ref": "#/definitions/headerParameterSubSchema"
+ },
+ {
+ "$ref": "#/definitions/formDataParameterSubSchema"
+ },
+ {
+ "$ref": "#/definitions/queryParameterSubSchema"
+ },
+ {
+ "$ref": "#/definitions/pathParameterSubSchema"
+ }
+ ]
+ },
+ "parameter": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/bodyParameter"
+ },
+ {
+ "$ref": "#/definitions/nonBodyParameter"
+ }
+ ]
+ },
+ "schema": {
+ "type": "object",
+ "description": "A deterministic version of a JSON Schema object.",
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ },
+ "properties": {
+ "$ref": {
+ "type": "string"
+ },
+ "format": {
+ "type": "string"
+ },
+ "title": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/title"
+ },
+ "description": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/description"
+ },
+ "default": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/default"
+ },
+ "multipleOf": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/multipleOf"
+ },
+ "maximum": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/maximum"
+ },
+ "exclusiveMaximum": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/exclusiveMaximum"
+ },
+ "minimum": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/minimum"
+ },
+ "exclusiveMinimum": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/exclusiveMinimum"
+ },
+ "maxLength": {
+ "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveInteger"
+ },
+ "minLength": {
+ "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0"
+ },
+ "pattern": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/pattern"
+ },
+ "maxItems": {
+ "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveInteger"
+ },
+ "minItems": {
+ "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0"
+ },
+ "uniqueItems": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/uniqueItems"
+ },
+ "maxProperties": {
+ "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveInteger"
+ },
+ "minProperties": {
+ "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0"
+ },
+ "required": {
+ "$ref": "http://json-schema.org/draft-04/schema#/definitions/stringArray"
+ },
+ "enum": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/enum"
+ },
+ "additionalProperties": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/schema"
+ },
+ {
+ "type": "boolean"
+ }
+ ],
+ "default": {
+
+ }
+ },
+ "type": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/type"
+ },
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/schema"
+ },
+ {
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "$ref": "#/definitions/schema"
+ }
+ }
+ ],
+ "default": {
+
+ }
+ },
+ "allOf": {
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "$ref": "#/definitions/schema"
+ }
+ },
+ "properties": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/definitions/schema"
+ },
+ "default": {
+
+ }
+ },
+ "discriminator": {
+ "type": "string"
+ },
+ "readOnly": {
+ "type": "boolean",
+ "default": false
+ },
+ "xml": {
+ "$ref": "#/definitions/xml"
+ },
+ "externalDocs": {
+ "$ref": "#/definitions/externalDocs"
+ },
+ "example": {
+
+ }
+ },
+ "additionalProperties": false
+ },
+ "fileSchema": {
+ "type": "object",
+ "description": "A deterministic version of a JSON Schema object.",
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "properties": {
+ "format": {
+ "type": "string"
+ },
+ "title": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/title"
+ },
+ "description": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/description"
+ },
+ "default": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/default"
+ },
+ "required": {
+ "$ref": "http://json-schema.org/draft-04/schema#/definitions/stringArray"
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "file"
+ ]
+ },
+ "readOnly": {
+ "type": "boolean",
+ "default": false
+ },
+ "externalDocs": {
+ "$ref": "#/definitions/externalDocs"
+ },
+ "example": {
+
+ }
+ },
+ "additionalProperties": false
+ },
+ "primitivesItems": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "string",
+ "number",
+ "integer",
+ "boolean",
+ "array"
+ ]
+ },
+ "format": {
+ "type": "string"
+ },
+ "items": {
+ "$ref": "#/definitions/primitivesItems"
+ },
+ "collectionFormat": {
+ "$ref": "#/definitions/collectionFormat"
+ },
+ "default": {
+ "$ref": "#/definitions/default"
+ },
+ "maximum": {
+ "$ref": "#/definitions/maximum"
+ },
+ "exclusiveMaximum": {
+ "$ref": "#/definitions/exclusiveMaximum"
+ },
+ "minimum": {
+ "$ref": "#/definitions/minimum"
+ },
+ "exclusiveMinimum": {
+ "$ref": "#/definitions/exclusiveMinimum"
+ },
+ "maxLength": {
+ "$ref": "#/definitions/maxLength"
+ },
+ "minLength": {
+ "$ref": "#/definitions/minLength"
+ },
+ "pattern": {
+ "$ref": "#/definitions/pattern"
+ },
+ "maxItems": {
+ "$ref": "#/definitions/maxItems"
+ },
+ "minItems": {
+ "$ref": "#/definitions/minItems"
+ },
+ "uniqueItems": {
+ "$ref": "#/definitions/uniqueItems"
+ },
+ "enum": {
+ "$ref": "#/definitions/enum"
+ },
+ "multipleOf": {
+ "$ref": "#/definitions/multipleOf"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ }
+ },
+ "security": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/securityRequirement"
+ },
+ "uniqueItems": true
+ },
+ "securityRequirement": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "uniqueItems": true
+ }
+ },
+ "xml": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "namespace": {
+ "type": "string"
+ },
+ "prefix": {
+ "type": "string"
+ },
+ "attribute": {
+ "type": "boolean",
+ "default": false
+ },
+ "wrapped": {
+ "type": "boolean",
+ "default": false
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ }
+ },
+ "tag": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "externalDocs": {
+ "$ref": "#/definitions/externalDocs"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ }
+ },
+ "securityDefinitions": {
+ "type": "object",
+ "additionalProperties": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/basicAuthenticationSecurity"
+ },
+ {
+ "$ref": "#/definitions/apiKeySecurity"
+ },
+ {
+ "$ref": "#/definitions/oauth2ImplicitSecurity"
+ },
+ {
+ "$ref": "#/definitions/oauth2PasswordSecurity"
+ },
+ {
+ "$ref": "#/definitions/oauth2ApplicationSecurity"
+ },
+ {
+ "$ref": "#/definitions/oauth2AccessCodeSecurity"
+ }
+ ]
+ }
+ },
+ "basicAuthenticationSecurity": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "basic"
+ ]
+ },
+ "description": {
+ "type": "string"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ }
+ },
+ "apiKeySecurity": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "type",
+ "name",
+ "in"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "apiKey"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "in": {
+ "type": "string",
+ "enum": [
+ "header",
+ "query"
+ ]
+ },
+ "description": {
+ "type": "string"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ }
+ },
+ "oauth2ImplicitSecurity": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "type",
+ "flow",
+ "authorizationUrl"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "oauth2"
+ ]
+ },
+ "flow": {
+ "type": "string",
+ "enum": [
+ "implicit"
+ ]
+ },
+ "scopes": {
+ "$ref": "#/definitions/oauth2Scopes"
+ },
+ "authorizationUrl": {
+ "type": "string",
+ "format": "uri"
+ },
+ "description": {
+ "type": "string"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ }
+ },
+ "oauth2PasswordSecurity": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "type",
+ "flow",
+ "tokenUrl"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "oauth2"
+ ]
+ },
+ "flow": {
+ "type": "string",
+ "enum": [
+ "password"
+ ]
+ },
+ "scopes": {
+ "$ref": "#/definitions/oauth2Scopes"
+ },
+ "tokenUrl": {
+ "type": "string",
+ "format": "uri"
+ },
+ "description": {
+ "type": "string"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ }
+ },
+ "oauth2ApplicationSecurity": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "type",
+ "flow",
+ "tokenUrl"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "oauth2"
+ ]
+ },
+ "flow": {
+ "type": "string",
+ "enum": [
+ "application"
+ ]
+ },
+ "scopes": {
+ "$ref": "#/definitions/oauth2Scopes"
+ },
+ "tokenUrl": {
+ "type": "string",
+ "format": "uri"
+ },
+ "description": {
+ "type": "string"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ }
+ },
+ "oauth2AccessCodeSecurity": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "type",
+ "flow",
+ "authorizationUrl",
+ "tokenUrl"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "oauth2"
+ ]
+ },
+ "flow": {
+ "type": "string",
+ "enum": [
+ "accessCode"
+ ]
+ },
+ "scopes": {
+ "$ref": "#/definitions/oauth2Scopes"
+ },
+ "authorizationUrl": {
+ "type": "string",
+ "format": "uri"
+ },
+ "tokenUrl": {
+ "type": "string",
+ "format": "uri"
+ },
+ "description": {
+ "type": "string"
+ }
+ },
+ "patternProperties": {
+ "^x-": {
+ "$ref": "#/definitions/vendorExtension"
+ }
+ }
+ },
+ "oauth2Scopes": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "mediaTypeList": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/mimeType"
+ },
+ "uniqueItems": true
+ },
+ "parametersList": {
+ "type": "array",
+ "description": "The parameters needed to send a valid API call.",
+ "additionalItems": false,
+ "items": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/parameter"
+ },
+ {
+ "$ref": "#/definitions/jsonReference"
+ }
+ ]
+ },
+ "uniqueItems": true
+ },
+ "schemesList": {
+ "type": "array",
+ "description": "The transfer protocol of the API.",
+ "items": {
+ "type": "string",
+ "enum": [
+ "http",
+ "https",
+ "ws",
+ "wss"
+ ]
+ },
+ "uniqueItems": true
+ },
+ "collectionFormat": {
+ "type": "string",
+ "enum": [
+ "csv",
+ "ssv",
+ "tsv",
+ "pipes"
+ ],
+ "default": "csv"
+ },
+ "collectionFormatWithMulti": {
+ "type": "string",
+ "enum": [
+ "csv",
+ "ssv",
+ "tsv",
+ "pipes",
+ "multi"
+ ],
+ "default": "csv"
+ },
+ "title": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/title"
+ },
+ "description": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/description"
+ },
+ "default": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/default"
+ },
+ "multipleOf": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/multipleOf"
+ },
+ "maximum": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/maximum"
+ },
+ "exclusiveMaximum": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/exclusiveMaximum"
+ },
+ "minimum": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/minimum"
+ },
+ "exclusiveMinimum": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/exclusiveMinimum"
+ },
+ "maxLength": {
+ "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveInteger"
+ },
+ "minLength": {
+ "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0"
+ },
+ "pattern": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/pattern"
+ },
+ "maxItems": {
+ "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveInteger"
+ },
+ "minItems": {
+ "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0"
+ },
+ "uniqueItems": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/uniqueItems"
+ },
+ "enum": {
+ "$ref": "http://json-schema.org/draft-04/schema#/properties/enum"
+ },
+ "jsonReference": {
+ "type": "object",
+ "required": [
+ "$ref"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "$ref": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+
\ No newline at end of file
diff --git a/lib/common/UserError.js b/lib/common/UserError.js
new file mode 100644
index 000000000..f420f8908
--- /dev/null
+++ b/lib/common/UserError.js
@@ -0,0 +1,15 @@
+/**
+ * constructor userError
+ * @constructor
+ * @param {*} message errorMessage
+ * @param {*} data additional data to be reported
+ */
+class UserError extends Error {
+ constructor(message, data) {
+ super(message);
+ this.name = 'UserError';
+ this.data = data || {};
+ }
+}
+
+module.exports = UserError;
diff --git a/lib/common/generateValidationError.js b/lib/common/generateValidationError.js
new file mode 100644
index 000000000..683cb2d83
--- /dev/null
+++ b/lib/common/generateValidationError.js
@@ -0,0 +1,79 @@
+const Ajv = require('ajv-draft-04'),
+ UserError = require('./UserError'),
+ addFormats = require('ajv-formats'),
+ openapi3Schema = require('../../assets/openapi3Schema.json'),
+ swagger2Schema = require('../../assets/swagger2Schema.json'),
+ openapi3Utils = require('../30XUtils/schemaUtils30X'),
+ swagger2Utils = require('../swaggerUtils/schemaUtilsSwagger'),
+ { jsonPointerDecodeAndReplace } = require('../jsonPointer');
+
+/**
+ * Constructs Error message from given AJV Validation Error object.
+ *
+ * @param {Object} ajvError - AJV Validation Error object (reference: https://ajv.js.org/#validation-errors)
+ * @returns {String} - Error message constructed (To be displayed as error message for invalid specs)
+ */
+function constructErrorMessage (ajvError) {
+ let message = 'Provided API Specification is invalid. ';
+
+ message += ajvError.message;
+
+ if (ajvError.params) {
+ message += ' ' + JSON.stringify(ajvError.params);
+ }
+
+ if (typeof ajvError.instancePath === 'string') {
+ message += ` at "${jsonPointerDecodeAndReplace(ajvError.instancePath)}"`;
+ }
+
+ return message;
+}
+
+/**
+ * Validates given OpenAPI specification against JSON schema of OpenAPI spec using AJV and
+ * generates UserError or Unhandled error depending upon type of error.
+ *
+ * @param {Object} definition - Parsed OAS definition
+ * @param {string} definitionVersion - Corresponding Definition version
+ * @param {*} error - Original Error object
+ * @returns {*} - Generated Error object
+ */
+function generateError (definition, definitionVersion, error) {
+ let ajv = new Ajv({
+ schemaId: 'auto',
+ strict: false
+ }),
+ validate,
+ valid = true;
+
+ // Log original error for better obseravibility in case of User errors
+ console.error(error);
+
+ addFormats(ajv);
+
+ if (definitionVersion === openapi3Utils.version) {
+ validate = ajv.compile(openapi3Schema);
+ }
+ else if (definitionVersion === swagger2Utils.version) {
+ validate = ajv.compile(swagger2Schema);
+ }
+
+ validate && (valid = validate(definition));
+
+ if (valid) {
+ if (error instanceof Error) {
+ return error;
+ }
+
+ const errorMessage = typeof error === 'string' ? error : _.get(error, 'message', 'Failed to generate collection.');
+
+ return new Error(errorMessage);
+ }
+ else {
+ return new UserError(constructErrorMessage(validate.errors[0]), error);
+ }
+}
+
+module.exports = {
+ generateError
+};
diff --git a/lib/common/js2xml.js b/lib/common/js2xml.js
new file mode 100644
index 000000000..95e4ba6e5
--- /dev/null
+++ b/lib/common/js2xml.js
@@ -0,0 +1,472 @@
+/* eslint-disable */
+
+/**
+ * This code is stripped down version of https://github.com/ibm-maximo-dev/xml-js
+ * Only essential part to convert JSON to XML is used here.
+ *
+ * Ideally there should be no updates needed to this code as it already handles all types of data for JSON object.
+ * But in case this need updates, take a look at below file specifically from which this logic was inspired from.
+ *
+ * https://github.com/ibm-maximo-dev/xml-js/blob/master/lib/js2xml.js
+ */
+
+var currentElement, currentElementName;
+
+const DEFAULT_OPTIONS = {
+ spaces: ' ',
+ compact: true
+}
+
+function isArray (value) {
+ if (Array.isArray) {
+ return Array.isArray(value);
+ }
+ // fallback for older browsers like IE 8
+ return Object.prototype.toString.call( value ) === '[object Array]';
+}
+
+// Options helper
+const helper = {
+ copyOptions: function (options) {
+ var key, copy = {};
+ for (key in options) {
+ if (options.hasOwnProperty(key)) {
+ copy[key] = options[key];
+ }
+ }
+ return copy;
+ },
+
+ ensureFlagExists: function (item, options) {
+ if (!(item in options) || typeof options[item] !== 'boolean') {
+ options[item] = false;
+ }
+ },
+
+ ensureSpacesExists: function (options) {
+ if (!('spaces' in options) || (typeof options.spaces !== 'number' && typeof options.spaces !== 'string')) {
+ options.spaces = 0;
+ }
+ },
+
+ ensureAlwaysArrayExists: function (options) {
+ if (!('alwaysArray' in options) || (typeof options.alwaysArray !== 'boolean' && !isArray(options.alwaysArray))) {
+ options.alwaysArray = false;
+ }
+ },
+
+ ensureKeyExists: function (key, options) {
+ if (!(key + 'Key' in options) || typeof options[key + 'Key'] !== 'string') {
+ options[key + 'Key'] = options.compact ? '_' + key : key;
+ }
+ },
+
+ checkFnExists: function (key, options) {
+ return key + 'Fn' in options;
+ }
+};
+
+function validateOptions(userOptions) {
+ var options = helper.copyOptions(userOptions);
+ helper.ensureFlagExists('ignoreDeclaration', options);
+ helper.ensureFlagExists('ignoreInstruction', options);
+ helper.ensureFlagExists('ignoreAttributes', options);
+ helper.ensureFlagExists('ignoreText', options);
+ helper.ensureFlagExists('ignoreComment', options);
+ helper.ensureFlagExists('ignoreCdata', options);
+ helper.ensureFlagExists('ignoreDoctype', options);
+ helper.ensureFlagExists('compact', options);
+ helper.ensureFlagExists('indentText', options);
+ helper.ensureFlagExists('indentCdata', options);
+ helper.ensureFlagExists('indentAttributes', options);
+ helper.ensureFlagExists('indentInstruction', options);
+ helper.ensureFlagExists('fullTagEmptyElement', options);
+ helper.ensureFlagExists('noQuotesForNativeAttributes', options);
+ helper.ensureSpacesExists(options);
+ if (typeof options.spaces === 'number') {
+ options.spaces = Array(options.spaces + 1).join(' ');
+ }
+ helper.ensureKeyExists('declaration', options);
+ helper.ensureKeyExists('instruction', options);
+ helper.ensureKeyExists('attributes', options);
+ helper.ensureKeyExists('text', options);
+ helper.ensureKeyExists('comment', options);
+ helper.ensureKeyExists('cdata', options);
+ helper.ensureKeyExists('doctype', options);
+ helper.ensureKeyExists('type', options);
+ helper.ensureKeyExists('name', options);
+ helper.ensureKeyExists('elements', options);
+ helper.checkFnExists('doctype', options);
+ helper.checkFnExists('instruction', options);
+ helper.checkFnExists('cdata', options);
+ helper.checkFnExists('comment', options);
+ helper.checkFnExists('text', options);
+ helper.checkFnExists('instructionName', options);
+ helper.checkFnExists('elementName', options);
+ helper.checkFnExists('attributeName', options);
+ helper.checkFnExists('attributeValue', options);
+ helper.checkFnExists('attributes', options);
+ helper.checkFnExists('fullTagEmptyElement', options);
+ return options;
+}
+
+function writeIndentation(options, depth, firstLine) {
+ return (!firstLine && options.spaces ? '\n' : '') + Array(depth + 1).join(options.spaces);
+}
+
+function writeAttributes(attributes, options, depth) {
+ if (options.ignoreAttributes) {
+ return '';
+ }
+ if ('attributesFn' in options) {
+ attributes = options.attributesFn(attributes, currentElementName, currentElement);
+ }
+ var key,
+ attr,
+ attrName,
+ attrPlusValue,
+ quote,
+ result = [];
+ // NOTE: we don't the length of the element name, so this is the best we can do
+ var attrLineWidth = (depth + 1) * options.spaces;
+ var wrapped = false;
+ for (key in attributes) {
+ if (
+ attributes.hasOwnProperty(key) &&
+ attributes[key] !== null &&
+ attributes[key] !== undefined
+ ) {
+ quote =
+ options.noQuotesForNativeAttributes &&
+ typeof attributes[key] !== "string"
+ ? ""
+ : '"';
+ attr = "" + attributes[key]; // ensure number and boolean are converted to String
+ attr = attr.replace(/"/g, """);
+ attr = attr.replace(/ options.indentAttributesWidth
+ ) {
+ result.push(writeIndentation(options, depth + 1, false));
+ attrLineWidth =
+ (depth + 1) * options.spaces + attrPlusValue.length + 1;
+ wrapped = true;
+ } else {
+ result.push(" ");
+ }
+ } else {
+ result.push(
+ options.spaces && options.indentAttributes
+ ? writeIndentation(options, depth + 1, false)
+ : " "
+ );
+ }
+ result.push(attrPlusValue);
+ }
+ }
+ if (
+ attributes &&
+ Object.keys(attributes).length &&
+ options.spaces &&
+ options.indentAttributes
+ ) {
+ if (
+ options.indentAttributesWidth &&
+ !wrapped
+ ) {
+ result.push(" ");
+ } else {
+ result.push(writeIndentation(options, depth, false));
+ }
+ }
+ return result.join('');
+}
+
+function writeDeclaration(declaration, options, depth) {
+ currentElement = declaration;
+ currentElementName = 'xml';
+ return options.ignoreDeclaration ? '' : '' + 'xml' + writeAttributes(declaration[options.attributesKey], options, depth) + '?>';
+}
+
+function writeInstruction(instruction, options, depth) {
+ if (options.ignoreInstruction) {
+ return '';
+ }
+ var key;
+ for (key in instruction) {
+ if (instruction.hasOwnProperty(key)) {
+ break;
+ }
+ }
+ var instructionName = 'instructionNameFn' in options ? options.instructionNameFn(key, instruction[key], currentElementName, currentElement) : key;
+ if (typeof instruction[key] === 'object') {
+ currentElement = instruction;
+ currentElementName = instructionName;
+ return '' + instructionName + writeAttributes(instruction[key][options.attributesKey], options, depth) + '?>';
+ } else {
+ var instructionValue = instruction[key] ? instruction[key] : '';
+ if ('instructionFn' in options) instructionValue = options.instructionFn(instructionValue, key, currentElementName, currentElement);
+ return '' + instructionName + (instructionValue ? ' ' + instructionValue : '') + '?>';
+ }
+}
+
+function writeComment(comment, options) {
+ return options.ignoreComment ? '' : '';
+}
+
+function writeCdata(cdata, options) {
+ return options.ignoreCdata ? '' : '', ']]]]>')) + ']]>';
+}
+
+function writeDoctype(doctype, options) {
+ return options.ignoreDoctype ? '' : '';
+}
+
+function writeText(text, options) {
+ if (options.ignoreText) return '';
+ text = '' + text; // ensure Number and Boolean are converted to String
+ text = text.replace(/&/g, '&'); // desanitize to avoid double sanitization
+ text = text.replace(/&/g, '&').replace(//g, '>');
+ return 'textFn' in options ? options.textFn(text, currentElementName, currentElement) : text;
+}
+
+function hasContent(element, options) {
+ var i;
+ if (element.elements && element.elements.length) {
+ for (i = 0; i < element.elements.length; ++i) {
+ switch (element.elements[i][options.typeKey]) {
+ case 'text':
+ if (options.indentText) {
+ return true;
+ }
+ break; // skip to next key
+ case 'cdata':
+ if (options.indentCdata) {
+ return true;
+ }
+ break; // skip to next key
+ case 'instruction':
+ if (options.indentInstruction) {
+ return true;
+ }
+ break; // skip to next key
+ case 'doctype':
+ case 'comment':
+ case 'element':
+ return true;
+ default:
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+function writeElement(element, options, depth) {
+ currentElement = element;
+ currentElementName = element.name;
+ var xml = [], elementName = 'elementNameFn' in options ? options.elementNameFn(element.name, element) : element.name;
+ xml.push('<' + elementName);
+ if (element[options.attributesKey]) {
+ xml.push(writeAttributes(element[options.attributesKey], options, depth));
+ }
+ var withClosingTag = element[options.elementsKey] && element[options.elementsKey].length || element[options.attributesKey] && element[options.attributesKey]['xml:space'] === 'preserve';
+ if (!withClosingTag) {
+ if ('fullTagEmptyElementFn' in options) {
+ withClosingTag = options.fullTagEmptyElementFn(element.name, element);
+ } else {
+ withClosingTag = options.fullTagEmptyElement;
+ }
+ }
+ if (withClosingTag) {
+ xml.push('>');
+ if (element[options.elementsKey] && element[options.elementsKey].length) {
+ xml.push(writeElements(element[options.elementsKey], options, depth + 1));
+ currentElement = element;
+ currentElementName = element.name;
+ }
+ xml.push(options.spaces && hasContent(element, options) ? '\n' + Array(depth + 1).join(options.spaces) : '');
+ xml.push('' + elementName + '>');
+ } else {
+ xml.push('/>');
+ }
+ return xml.join('');
+}
+
+function writeElements(elements, options, depth, firstLine) {
+ return elements.reduce(function (xml, element) {
+ var indent = writeIndentation(options, depth, firstLine && !xml);
+ switch (element.type) {
+ case 'element': return xml + indent + writeElement(element, options, depth);
+ case 'comment': return xml + indent + writeComment(element[options.commentKey], options);
+ case 'doctype': return xml + indent + writeDoctype(element[options.doctypeKey], options);
+ case 'cdata': return xml + (options.indentCdata ? indent : '') + writeCdata(element[options.cdataKey], options);
+ case 'text': return xml + (options.indentText ? indent : '') + writeText(element[options.textKey], options);
+ case 'instruction':
+ var instruction = {};
+ instruction[element[options.nameKey]] = element[options.attributesKey] ? element : element[options.instructionKey];
+ return xml + (options.indentInstruction ? indent : '') + writeInstruction(instruction, options, depth);
+ }
+ }, '');
+}
+
+function hasContentCompact(element, options, anyContent) {
+ var key;
+ for (key in element) {
+ if (element.hasOwnProperty(key)) {
+ switch (key) {
+ case options.parentKey:
+ case options.attributesKey:
+ break; // skip to next key
+ case options.textKey:
+ if (options.indentText || anyContent) {
+ return true;
+ }
+ break; // skip to next key
+ case options.cdataKey:
+ if (options.indentCdata || anyContent) {
+ return true;
+ }
+ break; // skip to next key
+ case options.instructionKey:
+ if (options.indentInstruction || anyContent) {
+ return true;
+ }
+ break; // skip to next key
+ case options.doctypeKey:
+ case options.commentKey:
+ return true;
+ default:
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+function writeElementCompact(element, name, options, depth, indent) {
+ currentElement = element;
+ currentElementName = name;
+ var elementName = 'elementNameFn' in options ? options.elementNameFn(name, element) : name;
+ if (typeof element === 'undefined' || element === null || element === '') {
+ return 'fullTagEmptyElementFn' in options && options.fullTagEmptyElementFn(name, element) || options.fullTagEmptyElement ? '<' + elementName + '>' + elementName + '>' : '<' + elementName + '/>';
+ }
+ var xml = [];
+ if (name) {
+ xml.push('<' + elementName);
+ if (typeof element !== 'object') {
+ xml.push('>' + writeText(element, options) + '' + elementName + '>');
+ return xml.join('');
+ }
+ if (element[options.attributesKey]) {
+ xml.push(writeAttributes(element[options.attributesKey], options, depth));
+ }
+ var withClosingTag = hasContentCompact(element, options, true) || element[options.attributesKey] && element[options.attributesKey]['xml:space'] === 'preserve';
+ if (!withClosingTag) {
+ if ('fullTagEmptyElementFn' in options) {
+ withClosingTag = options.fullTagEmptyElementFn(name, element);
+ } else {
+ withClosingTag = options.fullTagEmptyElement;
+ }
+ }
+ if (withClosingTag) {
+ xml.push('>');
+ } else {
+ xml.push('/>');
+ return xml.join('');
+ }
+ }
+ xml.push(writeElementsCompact(element, options, depth + 1, false));
+ currentElement = element;
+ currentElementName = name;
+ if (name) {
+ xml.push((indent ? writeIndentation(options, depth, false) : '') + '' + elementName + '>');
+ }
+ return xml.join('');
+}
+
+function writeElementsCompact(element, options, depth, firstLine) {
+ var i, key, nodes, xml = [];
+ for (key in element) {
+ if (element.hasOwnProperty(key)) {
+ nodes = isArray(element[key]) ? element[key] : [element[key]];
+ for (i = 0; i < nodes.length; ++i) {
+ switch (key) {
+ case options.declarationKey: xml.push(writeDeclaration(nodes[i], options, depth)); break;
+ case options.instructionKey: xml.push((options.indentInstruction ? writeIndentation(options, depth, firstLine) : '') + writeInstruction(nodes[i], options, depth)); break;
+ case options.attributesKey: case options.parentKey: break; // skip
+ case options.textKey: xml.push((options.indentText ? writeIndentation(options, depth, firstLine) : '') + writeText(nodes[i], options)); break;
+ case options.cdataKey: xml.push((options.indentCdata ? writeIndentation(options, depth, firstLine) : '') + writeCdata(nodes[i], options)); break;
+ case options.doctypeKey: xml.push(writeIndentation(options, depth, firstLine) + writeDoctype(nodes[i], options)); break;
+ case options.commentKey: xml.push(writeIndentation(options, depth, firstLine) + writeComment(nodes[i], options)); break;
+ default: xml.push(writeIndentation(options, depth, firstLine) + writeElementCompact(nodes[i], key, options, depth, hasContentCompact(nodes[i], options)));
+ }
+ firstLine = firstLine && !xml.length;
+ }
+ }
+ }
+ return xml.join('');
+}
+
+module.exports = function (js, indentChar) {
+ // If provided data is not JSON, return it as is. XML string could be already present as example.
+ if (typeof js !== 'object') {
+ return js;
+ }
+
+ try {
+ let options = DEFAULT_OPTIONS;
+
+ // Override indent character if defined.
+ indentChar && (options.spaces = indentChar);
+ options = validateOptions(options);
+ var xml = [];
+ currentElement = js;
+ currentElementName = '_root_';
+ if (options.compact) {
+ xml.push(writeElementsCompact(js, options, 0, true));
+ } else {
+ if (js[options.declarationKey]) {
+ xml.push(writeDeclaration(js[options.declarationKey], options, 0));
+ }
+ if (js[options.elementsKey] && js[options.elementsKey].length) {
+ xml.push(writeElements(js[options.elementsKey], options, 0, !xml.length));
+ }
+ }
+ return xml.join('');
+ } catch (err) {
+ console.error(err);
+
+ // Handle failures gracefully via returning the message inside body rather than failing entire collection
+ return 'Failed to generate XML data from provided Example.'
+ }
+};
diff --git a/lib/common/versionUtils.js b/lib/common/versionUtils.js
index 152e7fcdb..7ece46ace 100644
--- a/lib/common/versionUtils.js
+++ b/lib/common/versionUtils.js
@@ -21,7 +21,7 @@ const _ = require('lodash'),
* @returns {object} the resultant regular expresion using the provided data
*/
function getVersionRegexp({ key, version }) {
- return new RegExp(`${key}['|"]?:\\s?[\\\]?['|"]?${version}`);
+ return new RegExp(`${key}['|"]?\\s*:\\s*[\\\]?['|"]?${version}`);
}
/**
diff --git a/lib/schemaUtils.js b/lib/schemaUtils.js
index 0064c3a5f..0b45efcc5 100644
--- a/lib/schemaUtils.js
+++ b/lib/schemaUtils.js
@@ -13,6 +13,7 @@ const { formatDataPath, checkIsCorrectType, isKnownType } = require('./common/sc
deref = require('./deref.js'),
_ = require('lodash'),
xmlFaker = require('./xmlSchemaFaker.js'),
+ js2xml = require('./common/js2xml.js'),
openApiErr = require('./error.js'),
ajvValidationError = require('./ajValidation/ajvValidationError'),
utils = require('./utils.js'),
@@ -141,6 +142,24 @@ function verifyDeprecatedProperties(resolvedSchema, includeDeprecated) {
});
}
+/**
+ * Adds XML version content for XML specific bodies.
+ *
+ * @param {*} bodyContent - XML Body content
+ * @returns {*} - Body with correct XML version content
+ */
+function getXmlVersionContent (bodyContent) {
+ bodyContent = (typeof bodyContent === 'string') ? bodyContent : '';
+ const regExp = new RegExp('([<\\?xml]+[\\s{1,}]+[version="\\d.\\d"]+[\\sencoding="]+.{1,15}"\\?>)');
+ let xmlBody = bodyContent;
+
+ if (!bodyContent.match(regExp)) {
+ const versionContent = '\n';
+ xmlBody = versionContent + xmlBody;
+ }
+ return xmlBody;
+}
+
/**
* Safe wrapper for schemaFaker that resolves references and
* removes things that might make schemaFaker crash
@@ -651,7 +670,11 @@ module.exports = {
// adding children for the nodes in the trie
// start at the top-level and do a DFS
for (i = 0; i < pathLength; i++) {
- if (!currentNode.children[currentPath[i]]) {
+ /**
+ * Use hasOwnProperty to determine if property exists as certain JS fuction are present
+ * as part of each object. e.g. `constructor`.
+ */
+ if (!(typeof currentNode.children === 'object' && currentNode.children.hasOwnProperty(currentPath[i]))) {
// if the currentPath doesn't already exist at this node,
// add it as a folder
currentNode.addChildren(currentPath[i], new Node({
@@ -1392,7 +1415,7 @@ module.exports = {
* @return {object} responseBody, contentType header needed
*/
convertToPmResponseBody: function(contentObj, components, options, schemaCache) {
- var responseBody, cTypeHeader, hasComputedType, cTypes,
+ var responseBody, cTypeHeader, hasComputedType, cTypes, headerFamily,
isJsonLike = false;
if (!contentObj) {
return {
@@ -1428,11 +1451,17 @@ module.exports = {
};
}
}
+
+ headerFamily = this.getHeaderFamily(cTypeHeader);
responseBody = this.convertToPmBodyData(contentObj[cTypeHeader], REQUEST_TYPE.EXAMPLE, cTypeHeader,
PARAMETER_SOURCE.RESPONSE, options.indentCharacter, components, options, schemaCache);
- if (this.getHeaderFamily(cTypeHeader) === HEADER_TYPE.JSON) {
+
+ if (headerFamily === HEADER_TYPE.JSON) {
responseBody = JSON.stringify(responseBody, null, options.indentCharacter);
}
+ else if (cTypeHeader === TEXT_XML || cTypeHeader === APP_XML || headerFamily === HEADER_TYPE.XML) {
+ responseBody = getXmlVersionContent(responseBody);
+ }
else if (typeof responseBody !== 'string') {
if (cTypeHeader === MEDIA_TYPE_ALL_RANGES) {
if (!_.isObject(responseBody) && _.isFunction(_.get(responseBody, 'toString'))) {
@@ -1552,8 +1581,9 @@ module.exports = {
resolveTo = this.resolveToExampleOrSchema(requestType, options.requestParametersResolution,
options.exampleParametersResolution);
let concreteUtils = components && components.hasOwnProperty('concreteUtils') ?
- components.concreteUtils :
- DEFAULT_SCHEMA_UTILS;
+ components.concreteUtils :
+ DEFAULT_SCHEMA_UTILS,
+ headerFamily = this.getHeaderFamily(contentType);
if (_.isEmpty(bodyObj)) {
return bodyData;
@@ -1562,7 +1592,7 @@ module.exports = {
if (bodyObj.example && (resolveTo === 'example' || !bodyObj.schema)) {
if (bodyObj.example.hasOwnProperty('$ref')) {
bodyObj.example = this.getRefObject(bodyObj.example.$ref, components, options);
- if (this.getHeaderFamily(contentType) === HEADER_TYPE.JSON) {
+ if (headerFamily === HEADER_TYPE.JSON) {
// try to parse the example as JSON. OK if this fails
// eslint-disable-next-line max-depth
@@ -1574,10 +1604,19 @@ module.exports = {
}
}
bodyData = bodyObj.example;
+
+ // Convert example into XML if present as JSON data
+ if (contentType === TEXT_XML || contentType === APP_XML || headerFamily === HEADER_TYPE.XML) {
+ bodyData = js2xml(bodyData, indentCharacter);
+ }
}
else if (!_.isEmpty(bodyObj.examples) && (resolveTo === 'example' || !bodyObj.schema)) {
// take one of the examples as the body and not all
bodyData = this.getExampleData(bodyObj.examples, components, options);
+
+ if (contentType === TEXT_XML || contentType === APP_XML || headerFamily === HEADER_TYPE.XML) {
+ bodyData = js2xml(bodyData, indentCharacter);
+ }
}
else if (bodyObj.schema) {
if (bodyObj.schema.hasOwnProperty('$ref')) {
@@ -1589,6 +1628,9 @@ module.exports = {
resolvedSchema = this.getRefObject(bodyObj.schema.$ref, components, options);
bodyObj.schema = concreteUtils.addOuterPropsToRefSchemaIfIsSupported(resolvedSchema, outerProps);
}
+ else {
+ bodyObj.schema = this.getRefObject(bodyObj.schema.$ref, components, options);
+ }
}
if (options.schemaFaker) {
if (this.getHeaderFamily(contentType) === HEADER_TYPE.XML) {
@@ -1609,9 +1651,18 @@ module.exports = {
}
return '';
}
- // Do not fake the bodyData if the complexity is 10.
- bodyData = safeSchemaFaker(bodyObj.schema || {}, resolveTo, PROCESSING_TYPE.CONVERSION, parameterSourceOption,
- components, schemaFormat, schemaCache, options);
+
+ if (
+ resolveTo === 'example' &&
+ _.get(bodyObj.schema, 'example') !== undefined &&
+ (contentType === TEXT_XML || contentType === APP_XML || headerFamily === HEADER_TYPE.XML)
+ ) {
+ bodyData = js2xml(bodyObj.schema.example, indentCharacter);
+ }
+ else {
+ bodyData = safeSchemaFaker(bodyObj.schema || {}, resolveTo, PROCESSING_TYPE.CONVERSION, parameterSourceOption,
+ components, schemaFormat, schemaCache, options);
+ }
}
else {
// do not fake if the option is false
@@ -2096,17 +2147,7 @@ module.exports = {
};
}
else {
- let getXmlVersionContent = (bodyContent) => {
- const regExp = new RegExp('([<\\?xml]+[\\s{1,}]+[version="\\d.\\d"]+[\\sencoding="]+.{1,15}"\\?>)');
- let xmlBody = bodyContent;
-
- if (!bodyContent.match(regExp)) {
- const versionContent = '\n';
- xmlBody = versionContent + xmlBody;
- }
- return xmlBody;
- },
- headerFamily;
+ let headerFamily;
bodyData = this.convertToPmBodyData(contentObj[bodyType], requestType, bodyType,
PARAMETER_SOURCE.REQUEST, options.indentCharacter, components, options, schemaCache);
diff --git a/lib/schemapack.js b/lib/schemapack.js
index 8ebb7c130..bfb0743e7 100644
--- a/lib/schemapack.js
+++ b/lib/schemapack.js
@@ -28,6 +28,7 @@ const COLLECTION_NAME = 'Imported from OpenAPI 3.0',
schemaUtils = require('./schemaUtils'),
v2 = require('../libV2/index'),
{ getServersPathVars } = require('./common/schemaUtilsCommon.js'),
+ { generateError } = require('./common/generateValidationError.js'),
MODULE_VERSION = {
V1: 'v1',
V2: 'v2'
@@ -84,19 +85,28 @@ class SchemaPack {
return callback(new OpenApiErr('The schema must be validated before attempting conversion'));
}
- // We only convert if swagger is found otherwise this.openapi remains the same
- return convertToOAS30IfSwagger(getConcreteSchemaUtils(this.input), this.openapi, (error, convertedOpenAPI) => {
- if (error) {
- return callback(error);
- }
+ try {
+ // We only convert if swagger is found otherwise this.openapi remains the same
+ return convertToOAS30IfSwagger(getConcreteSchemaUtils(this.input), this.openapi, (err, convertedOpenAPI) => {
+ if (err) {
+ const error = generateError(this.openapi, _.get(this.validationResult, 'specificationVersion'), err);
- this.openapi = convertedOpenAPI;
+ return callback(error);
+ }
- this.concreteUtils = concreteUtils;
- this.specComponents = concreteUtils.getRequiredData(this.openapi);
+ this.openapi = convertedOpenAPI;
- v2.convertV2(this, callback);
- });
+ this.concreteUtils = concreteUtils;
+ this.specComponents = concreteUtils.getRequiredData(this.openapi);
+
+ v2.convertV2(this, callback);
+ });
+ }
+ catch (err) {
+ const error = generateError(this.openapi, _.get(this.validationResult, 'specificationVersion'), err);
+
+ return callback(error);
+ }
}
// need to store the schema here
@@ -300,124 +310,135 @@ class SchemaPack {
return callback(new OpenApiErr('The schema must be validated before attempting conversion'));
}
- // We only convert if swagger is found otherwise this.openapi remains the same
- convertToOAS30IfSwagger(concreteUtils, this.openapi, (error, newOpenapi) => {
- if (error) {
- return callback(error);
- }
+ try {
+ // We only convert if swagger is found otherwise this.openapi remains the same
+ convertToOAS30IfSwagger(concreteUtils, this.openapi, (err, newOpenapi) => {
+ if (err) {
+ const error = generateError(this.openapi, _.get(this.validationResult, 'specificationVersion'), err);
- this.openapi = newOpenapi;
- // this cannot be attempted before validation
- specComponentsAndUtils = { concreteUtils };
- Object.assign(specComponentsAndUtils, concreteUtils.getRequiredData(this.openapi));
+ return callback(error);
+ }
- // create and sanitize basic spec
- openapi = this.openapi;
- openapi.servers = _.isEmpty(openapi.servers) ? [{ url: '/' }] : openapi.servers;
- openapi.securityDefs = _.get(openapi, 'components.securitySchemes', {});
- openapi.baseUrl = _.get(openapi, 'servers.0.url', '{{baseURL}}');
+ this.openapi = newOpenapi;
+ // this cannot be attempted before validation
+ specComponentsAndUtils = { concreteUtils };
+ Object.assign(specComponentsAndUtils, concreteUtils.getRequiredData(this.openapi));
- // TODO: Multiple server variables need to be saved as environments
- openapi.baseUrlVariables = _.get(openapi, 'servers.0.variables');
+ // create and sanitize basic spec
+ openapi = this.openapi;
+ openapi.servers = _.isEmpty(openapi.servers) ? [{ url: '/' }] : openapi.servers;
+ openapi.securityDefs = _.get(openapi, 'components.securitySchemes', {});
+ openapi.baseUrl = _.get(openapi, 'servers.0.url', '{{baseURL}}');
- // Fix {scheme} and {path} vars in the URL to :scheme and :path
- openapi.baseUrl = schemaUtils.fixPathVariablesInUrl(openapi.baseUrl);
+ // TODO: Multiple server variables need to be saved as environments
+ openapi.baseUrlVariables = _.get(openapi, 'servers.0.variables');
- // Creating a new instance of a Postman collection
- // All generated folders and requests will go inside this
- generatedStore.collection = new sdk.Collection({
- info: {
- name: _.isEmpty(_.get(openapi, 'info.title')) ? COLLECTION_NAME : _.get(openapi, 'info.title')
- }
- });
+ // Fix {scheme} and {path} vars in the URL to :scheme and :path
+ openapi.baseUrl = schemaUtils.fixPathVariablesInUrl(openapi.baseUrl);
- if (openapi.security) {
- authHelper = schemaUtils.getAuthHelper(openapi, openapi.security);
- if (authHelper) {
- generatedStore.collection.auth = authHelper;
- }
- }
- // ---- Collection Variables ----
- // adding the collection variables for all the necessary root level variables
- // and adding them to the collection variables
- schemaUtils.convertToPmCollectionVariables(
- openapi.baseUrlVariables,
- 'baseUrl',
- openapi.baseUrl
- ).forEach((element) => {
- generatedStore.collection.variables.add(element);
- });
+ // Creating a new instance of a Postman collection
+ // All generated folders and requests will go inside this
+ generatedStore.collection = new sdk.Collection({
+ info: {
+ name: _.isEmpty(_.get(openapi, 'info.title')) ? COLLECTION_NAME : _.get(openapi, 'info.title')
+ }
+ });
- generatedStore.collection.describe(schemaUtils.getCollectionDescription(openapi));
+ if (openapi.security) {
+ authHelper = schemaUtils.getAuthHelper(openapi, openapi.security);
+ if (authHelper) {
+ generatedStore.collection.auth = authHelper;
+ }
+ }
+ // ---- Collection Variables ----
+ // adding the collection variables for all the necessary root level variables
+ // and adding them to the collection variables
+ schemaUtils.convertToPmCollectionVariables(
+ openapi.baseUrlVariables,
+ 'baseUrl',
+ openapi.baseUrl
+ ).forEach((element) => {
+ generatedStore.collection.variables.add(element);
+ });
- // Only change the stack limit if the optimizeConversion option is true
- if (options.optimizeConversion) {
- // Deciding stack limit based on size of the schema, number of refs and number of paths.
- analysis = schemaUtils.analyzeSpec(openapi);
+ generatedStore.collection.describe(schemaUtils.getCollectionDescription(openapi));
- // Update options on the basis of analysis.
- options = schemaUtils.determineOptions(analysis, options);
- }
- Object.assign(this.analytics, analysis);
- Object.assign(this.analytics, {
- assignedStack: options.stackLimit,
- complexityScore: options.complexityScore
- });
+ // Only change the stack limit if the optimizeConversion option is true
+ if (options.optimizeConversion) {
+ // Deciding stack limit based on size of the schema, number of refs and number of paths.
+ analysis = schemaUtils.analyzeSpec(openapi);
- // ---- Collection Items ----
- // Adding the collection items from openapi spec based on folderStrategy option
- // For tags, All operations are grouped based on respective tags object
- // For paths, All operations are grouped based on corresponding paths
- try {
- if (options.folderStrategy === 'tags') {
- schemaUtils.addCollectionItemsUsingTags(
- openapi,
- generatedStore,
- specComponentsAndUtils,
- options,
- schemaCache
- );
+ // Update options on the basis of analysis.
+ options = schemaUtils.determineOptions(analysis, options);
}
- else {
- schemaUtils.addCollectionItemsUsingPaths(
- openapi,
- generatedStore,
- specComponentsAndUtils,
- options,
- schemaCache
- );
+ Object.assign(this.analytics, analysis);
+ Object.assign(this.analytics, {
+ assignedStack: options.stackLimit,
+ complexityScore: options.complexityScore
+ });
+
+ // ---- Collection Items ----
+ // Adding the collection items from openapi spec based on folderStrategy option
+ // For tags, All operations are grouped based on respective tags object
+ // For paths, All operations are grouped based on corresponding paths
+ try {
+ if (options.folderStrategy === 'tags') {
+ schemaUtils.addCollectionItemsUsingTags(
+ openapi,
+ generatedStore,
+ specComponentsAndUtils,
+ options,
+ schemaCache
+ );
+ }
+ else {
+ schemaUtils.addCollectionItemsUsingPaths(
+ openapi,
+ generatedStore,
+ specComponentsAndUtils,
+ options,
+ schemaCache
+ );
+ }
+
+ if (options.includeWebhooks) {
+ schemaUtils.addCollectionItemsFromWebhooks(
+ openapi,
+ generatedStore,
+ specComponentsAndUtils,
+ options,
+ schemaCache
+ );
+ }
}
+ catch (e) {
+ const error = generateError(this.openapi, _.get(this.validationResult, 'specificationVersion'), e);
- if (options.includeWebhooks) {
- schemaUtils.addCollectionItemsFromWebhooks(
- openapi,
- generatedStore,
- specComponentsAndUtils,
- options,
- schemaCache
- );
+ return callback(error);
}
- }
- catch (e) {
- return callback(e);
- }
- collectionJSON = generatedStore.collection.toJSON();
+ collectionJSON = generatedStore.collection.toJSON();
- // this needs to be deleted as even if version is not specified to sdk,
- // it returns a version property with value set as undefined
- // this fails validation against v2.1 collection schema definition.
- delete collectionJSON.info.version;
+ // this needs to be deleted as even if version is not specified to sdk,
+ // it returns a version property with value set as undefined
+ // this fails validation against v2.1 collection schema definition.
+ delete collectionJSON.info.version;
- return callback(null, {
- result: true,
- output: [{
- type: 'collection',
- data: collectionJSON
- }],
- analytics: this.analytics
+ return callback(null, {
+ result: true,
+ output: [{
+ type: 'collection',
+ data: collectionJSON
+ }],
+ analytics: this.analytics
+ });
});
- });
+ }
+ catch (err) {
+ const error = generateError(this.openapi, _.get(this.validationResult, 'specificationVersion'), err);
+
+ return callback(error);
+ }
}
/**
diff --git a/libV2/schemaUtils.js b/libV2/schemaUtils.js
index 44a355240..ed66390fb 100644
--- a/libV2/schemaUtils.js
+++ b/libV2/schemaUtils.js
@@ -5,6 +5,7 @@ const schemaFaker = require('../assets/json-schema-faker'),
_ = require('lodash'),
mergeAllOf = require('json-schema-merge-allof'),
xmlFaker = require('./xmlSchemaFaker.js'),
+ js2xml = require('../lib/common/js2xml'),
URLENCODED = 'application/x-www-form-urlencoded',
APP_JSON = 'application/json',
APP_JS = 'application/javascript',
@@ -1067,6 +1068,7 @@ let QUERYPARAM = 'query',
resolveRequestBodyData = (context, requestBodySchema, bodyType) => {
let { parametersResolution, indentCharacter } = context.computedOptions,
+ headerFamily = getHeaderFamily(bodyType),
bodyData = '',
shouldGenerateFromExample = parametersResolution === 'example',
example,
@@ -1128,6 +1130,11 @@ let QUERYPARAM = 'query',
requestBodySchema = requestBodySchema.schema || requestBodySchema;
requestBodySchema = resolveSchema(context, requestBodySchema);
+ // If schema object has example defined, try to use that if no example is defiend at request body level
+ if (example === undefined && _.get(requestBodySchema, 'example') !== undefined) {
+ example = requestBodySchema.example;
+ }
+
if (shouldGenerateFromExample && (example !== undefined || examples)) {
/**
* Here it could be example or examples (plural)
@@ -1135,7 +1142,12 @@ let QUERYPARAM = 'query',
*/
const exampleData = example || getExampleData(context, examples);
- bodyData = exampleData;
+ if (bodyType === APP_XML || bodyType === TEXT_XML || headerFamily === HEADER_TYPE.XML) {
+ bodyData = js2xml(exampleData, indentCharacter);
+ }
+ else {
+ bodyData = exampleData;
+ }
}
else if (requestBodySchema) {
requestBodySchema = requestBodySchema.schema || requestBodySchema;
@@ -1144,7 +1156,7 @@ let QUERYPARAM = 'query',
requestBodySchema = resolveSchema(context, requestBodySchema);
}
- if (bodyType === APP_XML || bodyType === TEXT_XML) {
+ if (bodyType === APP_XML || bodyType === TEXT_XML || headerFamily === HEADER_TYPE.XML) {
return xmlFaker(null, requestBodySchema, indentCharacter);
}
diff --git a/package-lock.json b/package-lock.json
index 9a38dfd2f..3f3022a58 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,15 +1,16 @@
{
"name": "openapi-to-postmanv2",
- "version": "4.12.0",
+ "version": "4.13.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "openapi-to-postmanv2",
- "version": "4.12.0",
+ "version": "4.13.0",
"license": "Apache-2.0",
"dependencies": {
- "ajv": "8.1.0",
+ "ajv": "8.5.0",
+ "ajv-draft-04": "1.0.0",
"ajv-formats": "2.1.1",
"async": "3.2.4",
"commander": "2.20.3",
@@ -559,9 +560,9 @@
}
},
"node_modules/ajv": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.1.0.tgz",
- "integrity": "sha512-B/Sk2Ix7A36fs/ZkuGLIR86EdjbgR6fsAcbx9lOP/QBSXujDNbVmIS/U4Itz5k8fPFDeVZl/zQ/gJW4Jrq6XjQ==",
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.5.0.tgz",
+ "integrity": "sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
@@ -573,6 +574,19 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
+ "node_modules/ajv-draft-04": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz",
+ "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==",
+ "peerDependencies": {
+ "ajv": "^8.5.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
"node_modules/ajv-formats": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
@@ -6004,9 +6018,9 @@
}
},
"ajv": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.1.0.tgz",
- "integrity": "sha512-B/Sk2Ix7A36fs/ZkuGLIR86EdjbgR6fsAcbx9lOP/QBSXujDNbVmIS/U4Itz5k8fPFDeVZl/zQ/gJW4Jrq6XjQ==",
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.5.0.tgz",
+ "integrity": "sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ==",
"requires": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
@@ -6014,6 +6028,12 @@
"uri-js": "^4.2.2"
}
},
+ "ajv-draft-04": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz",
+ "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==",
+ "requires": {}
+ },
"ajv-formats": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
diff --git a/package.json b/package.json
index 46090c0f2..a7544ceee 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "openapi-to-postmanv2",
- "version": "4.12.0",
+ "version": "4.13.0",
"description": "Convert a given OpenAPI specification to Postman Collection v2.0",
"homepage": "https://github.com/postmanlabs/openapi-to-postman",
"bugs": "https://github.com/postmanlabs/openapi-to-postman/issues",
@@ -116,7 +116,8 @@
"openapi2postmanv2": "./bin/openapi2postmanv2.js"
},
"dependencies": {
- "ajv": "8.1.0",
+ "ajv": "8.5.0",
+ "ajv-draft-04": "1.0.0",
"ajv-formats": "2.1.1",
"async": "3.2.4",
"commander": "2.20.3",
diff --git a/test/data/valid_swagger/yaml/xml_example.yaml b/test/data/valid_swagger/yaml/xml_example.yaml
new file mode 100644
index 000000000..35a1589a7
--- /dev/null
+++ b/test/data/valid_swagger/yaml/xml_example.yaml
@@ -0,0 +1,233 @@
+swagger: '2.0'
+info:
+ title: YAML data
+ version: '1.0'
+schemes:
+ - https
+securityDefinitions:
+ Bearer:
+ description: Authorization 'Bearer' token
+ in: header
+ name: Authorization
+ type: apiKey
+tags:
+ - name: client
+ description: Client resources
+paths:
+ /client:
+ get:
+ deprecated: false
+ summary: Query Client
+ produces:
+ - application/xml
+ responses:
+ '200':
+ description: OK
+ schema:
+ $ref: '#/definitions/Data'
+ post:
+ deprecated: false
+ summary: Query Client
+ produces:
+ - application/xml
+ responses:
+ '200':
+ description: OK
+ schema:
+ type: object
+ properties:
+ CstmrPmtStsRpt:
+ type: object
+ properties:
+ GrpHdr:
+ type: object
+ properties:
+ MsgId:
+ type: string
+ CreDtTm:
+ type: string
+ InitgPty:
+ type: object
+ properties:
+ Id:
+ type: object
+ properties:
+ OrgId:
+ type: object
+ properties:
+ BICOrBEI:
+ type: string
+ required:
+ - BICOrBEI
+ required:
+ - OrgId
+ required:
+ - Id
+ required:
+ - MsgId
+ - CreDtTm
+ - InitgPty
+ OrgnlGrpInfAndSts:
+ type: object
+ properties:
+ OrgnlMsgId:
+ type: string
+ Orgn1MsgNmId:
+ type: string
+ OrgnlCreDtTm:
+ type: string
+ Orgn1NbOfTxs:
+ type: string
+ required:
+ - OrgnlMsgId
+ - Orgn1MsgNmId
+ - OrgnlCreDtTm
+ - Orgn1NbOfTxs
+ OrgnlPmtInfAndSts:
+ type: array
+ items:
+ type: object
+ properties:
+ OrgnlPmtInfId:
+ type: string
+ TxInfAndSts:
+ type: object
+ properties:
+ OrgnlEndToEndId:
+ type: string
+ TxSts:
+ type: string
+ required:
+ - OrgnlEndToEndId
+ - TxSts
+ required:
+ - OrgnlPmtInfId
+ - TxInfAndSts
+ required:
+ - GrpHdr
+ - OrgnlGrpInfAndSts
+ - OrgnlPmtInfAndSts
+ required:
+ - CstmrPmtStsRpt
+ examples:
+ application/xml:
+ CstmrPmtStsRpt:
+ GrpHdr:
+ MsgId: 20201213-PSR/1798570726
+ InitgPty:
+ Id:
+ OrgId:
+ BICOrBEI: US33
+ OrgnlGrpInfAndSts:
+ OrgnlMsgId: '100060058'
+ Orgn1MsgNmId: pain.001.02
+ OrgnlCreDtTm: '2023-05-16T14:35:23-05:00'
+ Orgn1NbOfTxs: '1'
+ OrgnlPmtInfAndSts:
+ - OrgnlPmtInfId: ASIA
+ TxInfAndSts:
+ OrgnlEndToEndId: ASIADD
+ TxSts: ACTC
+ - OrgnlPmtInfId: EU
+ TxInfAndSts:
+ OrgnlEndToEndId: EUDD
+ TxSts: EUTC
+definitions:
+ Data:
+ type: object
+ properties:
+ CstmrPmtStsRpt:
+ type: object
+ properties:
+ GrpHdr:
+ type: object
+ properties:
+ MsgId:
+ type: string
+ CreDtTm:
+ type: string
+ InitgPty:
+ type: object
+ properties:
+ Id:
+ type: object
+ properties:
+ OrgId:
+ type: object
+ properties:
+ BICOrBEI:
+ type: string
+ required:
+ - BICOrBEI
+ required:
+ - OrgId
+ required:
+ - Id
+ required:
+ - MsgId
+ - CreDtTm
+ - InitgPty
+ OrgnlGrpInfAndSts:
+ type: object
+ properties:
+ OrgnlMsgId:
+ type: string
+ Orgn1MsgNmId:
+ type: string
+ OrgnlCreDtTm:
+ type: string
+ Orgn1NbOfTxs:
+ type: string
+ required:
+ - OrgnlMsgId
+ - Orgn1MsgNmId
+ - OrgnlCreDtTm
+ - Orgn1NbOfTxs
+ OrgnlPmtInfAndSts:
+ type: array
+ items:
+ type: object
+ properties:
+ OrgnlPmtInfId:
+ type: string
+ TxInfAndSts:
+ type: object
+ properties:
+ OrgnlEndToEndId:
+ type: string
+ TxSts:
+ type: string
+ required:
+ - OrgnlEndToEndId
+ - TxSts
+ required:
+ - OrgnlPmtInfId
+ - TxInfAndSts
+ required:
+ - GrpHdr
+ - OrgnlGrpInfAndSts
+ - OrgnlPmtInfAndSts
+ required:
+ - CstmrPmtStsRpt
+ example:
+ CstmrPmtStsRpt:
+ GrpHdr:
+ MsgId: 20231213-PSR/1798570726
+ InitgPty:
+ Id:
+ OrgId:
+ BICOrBEI: US33
+ OrgnlGrpInfAndSts:
+ OrgnlMsgId: '100060058'
+ Orgn1MsgNmId: pain.001.02
+ OrgnlCreDtTm: '2023-05-16T14:35:23-05:00'
+ Orgn1NbOfTxs: '1'
+ OrgnlPmtInfAndSts:
+ - OrgnlPmtInfId: ASIA
+ TxInfAndSts:
+ OrgnlEndToEndId: ASIADD
+ TxSts: ACTC
+ - OrgnlPmtInfId: EU
+ TxInfAndSts:
+ OrgnlEndToEndId: EUDD
+ TxSts: EUTC
diff --git a/test/unit/base.test.js b/test/unit/base.test.js
index bbe204c75..ffd8b8312 100644
--- a/test/unit/base.test.js
+++ b/test/unit/base.test.js
@@ -1593,7 +1593,8 @@ describe('CONVERT FUNCTION TESTS ', function() {
' (boolean)\n' +
' (number)\n' +
'',
- expectedResponseBody = '\n' +
+ expectedResponseBody = '\n' +
+ '\n' +
' (integer)\n' +
' (string)\n' +
' (boolean)\n' +
@@ -1623,7 +1624,8 @@ describe('CONVERT FUNCTION TESTS ', function() {
' (string)\n' +
' (boolean)\n' +
'',
- expectedResponseBody = '\n' +
+ expectedResponseBody = '\n' +
+ '\n' +
' (integer)\n' +
' (string)\n' +
' (boolean)\n' +
@@ -1657,7 +1659,8 @@ describe('CONVERT FUNCTION TESTS ', function() {
' (string)\n' +
' (boolean)\n' +
'',
- expectedResponseBody = '\n' +
+ expectedResponseBody = '\n' +
+ '\n' +
' (integer)\n' +
' (string)\n' +
' (boolean)\n' +
@@ -1696,7 +1699,8 @@ describe('CONVERT FUNCTION TESTS ', function() {
' (string)\n' +
' (boolean)\n' +
'',
- expectedResponseBody = '\n' +
+ expectedResponseBody = '\n' +
+ '\n' +
' (integer)\n' +
' (string)\n' +
' (boolean)\n' +
@@ -1737,7 +1741,8 @@ describe('CONVERT FUNCTION TESTS ', function() {
' (boolean)\n' +
' \n' +
'',
- expectedResponseBody = '\n' +
+ expectedResponseBody = '\n' +
+ '\n' +
' \n' +
' (integer)\n' +
' (string)\n' +
@@ -1961,8 +1966,8 @@ describe('CONVERT FUNCTION TESTS ', function() {
expect(result.output[0].type).to.have.equal('collection');
expect(result.output[0].data).to.have.property('info');
expect(result.output[0].data).to.have.property('item');
+ done();
});
- done();
});
it('must read values consumes', function (done) {
@@ -2059,6 +2064,89 @@ describe('CONVERT FUNCTION TESTS ', function() {
.and.to.have.all.keys('content', 'paging');
});
});
+
+ it('Should convert a swagger document with XML example correctly', function(done) {
+ const fileData = fs.readFileSync(path.join(__dirname, SWAGGER_20_FOLDER_YAML, 'xml_example.yaml'), 'utf8'),
+ input = {
+ type: 'string',
+ data: fileData
+ };
+ Converter.convert(input, { }, (error, result) => {
+ expect(error).to.be.null;
+ expect(result.result).to.equal(true);
+ expect(result.output.length).to.equal(1);
+ expect(result.output[0].type).to.have.equal('collection');
+ expect(result.output[0].data).to.have.property('info');
+ expect(result.output[0].data).to.have.property('item');
+ expect(result.output[0].data.item[0].item[0].response[0].body).to.eql(`
+
+
+ 20231213-PSR/1798570726
+
+
+
+ US33
+
+
+
+
+
+ 100060058
+ pain.001.02
+ 2023-05-16T14:35:23-05:00
+ 1
+
+
+ ASIA
+
+ ASIADD
+ ACTC
+
+
+
+ EU
+
+ EUDD
+ EUTC
+
+
+`);
+ expect(result.output[0].data.item[0].item[1].response[0].body).to.eql(`
+
+
+ 20201213-PSR/1798570726
+
+
+
+ US33
+
+
+
+
+
+ 100060058
+ pain.001.02
+ 2023-05-16T14:35:23-05:00
+ 1
+
+
+ ASIA
+
+ ASIADD
+ ACTC
+
+
+
+ EU
+
+ EUDD
+ EUTC
+
+
+`);
+ done();
+ });
+ });
});
describe('requestNameSource option', function() {
diff --git a/test/unit/convertV2.test.js b/test/unit/convertV2.test.js
index e4516f19f..0a3c09cb7 100644
--- a/test/unit/convertV2.test.js
+++ b/test/unit/convertV2.test.js
@@ -1872,8 +1872,8 @@ describe('The convert v2 Function', function() {
expect(result.output[0].type).to.have.equal('collection');
expect(result.output[0].data).to.have.property('info');
expect(result.output[0].data).to.have.property('item');
+ done();
});
- done();
});
it('must read values consumes', function (done) {
@@ -1973,6 +1973,89 @@ describe('The convert v2 Function', function() {
.and.to.have.all.keys('content', 'paging');
});
});
+
+ it('Should convert a swagger document with XML example correctly', function(done) {
+ const fileData = fs.readFileSync(path.join(__dirname, SWAGGER_20_FOLDER_YAML, 'xml_example.yaml'), 'utf8'),
+ input = {
+ type: 'string',
+ data: fileData
+ };
+ Converter.convertV2(input, { parametersResolution: 'Example' }, (error, result) => {
+ expect(error).to.be.null;
+ expect(result.result).to.equal(true);
+ expect(result.output.length).to.equal(1);
+ expect(result.output[0].type).to.have.equal('collection');
+ expect(result.output[0].data).to.have.property('info');
+ expect(result.output[0].data).to.have.property('item');
+ expect(result.output[0].data.item[0].item[0].response[0].body).to.eql(`
+
+
+ 20231213-PSR/1798570726
+
+
+
+ US33
+
+
+
+
+
+ 100060058
+ pain.001.02
+ 2023-05-16T14:35:23-05:00
+ 1
+
+
+ ASIA
+
+ ASIADD
+ ACTC
+
+
+
+ EU
+
+ EUDD
+ EUTC
+
+
+`);
+ expect(result.output[0].data.item[0].item[1].response[0].body).to.eql(`
+
+
+ 20201213-PSR/1798570726
+
+
+
+ US33
+
+
+
+
+
+ 100060058
+ pain.001.02
+ 2023-05-16T14:35:23-05:00
+ 1
+
+
+ ASIA
+
+ ASIADD
+ ACTC
+
+
+
+ EU
+
+ EUDD
+ EUTC
+
+
+`);
+ done();
+ });
+ });
});
it('Should honor indent character option', function(done) {
diff --git a/test/unit/faker.test.js b/test/unit/faker.test.js
index e2fc486e7..465e4ae62 100644
--- a/test/unit/faker.test.js
+++ b/test/unit/faker.test.js
@@ -121,4 +121,37 @@ describe('JSON SCHEMA FAKER TESTS', function () {
expect(value.name).to.be.a('string');
});
});
+
+ it('Should successsfully generate data for certain patterns that can generate empty string', function () {
+ const schema = {
+ 'maxLength': 63,
+ 'minLength': 2,
+ 'pattern': '^[A-Za-z !#$%&0-9,\'*+\\-.()/:;=@\\\\_\\[\\]`{}]*$',
+ 'type': 'string',
+ 'description': 'The exact name on the credit card.'
+ };
+
+ var fakedData = schemaFaker(schema);
+ expect(fakedData).to.be.an('string');
+ expect(fakedData.length >= 2).to.be.true;
+ expect(fakedData.length <= 63).to.be.true;
+ });
+
+ it('Should successsfully generate data iff required is defined as string', function () {
+ const schema = {
+ type: 'object',
+ required: 'timebase',
+ properties: {
+ timebase: { type: 'string' },
+ linkid: { type: 'string' },
+ chartRef: { type: 'string' }
+ }
+ };
+
+ var fakedData = schemaFaker(schema);
+ expect(fakedData).to.be.an('object');
+ expect(fakedData.timebase).to.be.a('string');
+ expect(fakedData.linkid).to.be.a('string');
+ expect(fakedData.chartRef).to.be.a('string');
+ });
});
diff --git a/test/unit/util.test.js b/test/unit/util.test.js
index 54d1878e5..ef2f9befe 100644
--- a/test/unit/util.test.js
+++ b/test/unit/util.test.js
@@ -686,6 +686,45 @@ describe('SCHEMA UTILITY FUNCTION TESTS ', function () {
done();
});
+
+ it('should generate trie for definition with certain path segment same as JS object function names correctly',
+ function (done) {
+ var openapi = {
+ 'openapi': '3.0.0',
+ 'info': {
+ 'version': '1.0.0',
+ 'title': 'Swagger Petstore',
+ 'license': {
+ 'name': 'MIT'
+ }
+ },
+ 'servers': [
+ {
+ 'url': 'http://petstore.swagger.io/{v1}'
+ }
+ ],
+ 'paths': {
+ '/constructor/v3/update-constructor': {
+ 'get': {
+ 'summary': 'List all pets',
+ 'operationId': 'listPets',
+ 'responses': {
+ '200': {
+ 'description': 'An paged array of pets'
+ }
+ }
+ }
+ }
+ }
+ },
+ output = SchemaUtils.generateTrieFromPaths(openapi),
+ root = output.tree.root;
+
+ expect(root.children).to.be.an('object').that.has.all.keys('constructor');
+ expect(root.children.constructor.requestCount).to.equal(1);
+
+ done();
+ });
});
describe('convertPathVariables', function() {
@@ -2293,6 +2332,7 @@ describe('SCHEMA UTILITY FUNCTION TESTS ', function () {
}).responseBody;
expect(pmResponseBody).to.equal(
[
+ '',
'',
' (string)',
' ',
@@ -2415,7 +2455,8 @@ describe('SCHEMA UTILITY FUNCTION TESTS ', function () {
pmResponse = SchemaUtils.convertToPmResponse(response, code, {}, {},
{ schemaFaker: true, indentCharacter: ' ' }).toJSON();
- expect(pmResponse.body).to.equal('\n (integer)\n (string)\n');
+ expect(pmResponse.body).to.equal('\n' +
+ '\n (integer)\n (string)\n');
expect(pmResponse.name).to.equal(response.description);
expect(pmResponse.code).to.equal(200);
expect(pmResponse._postman_previewlanguage).to.equal('xml');
diff --git a/test/unit/versionUtils.test.js b/test/unit/versionUtils.test.js
index 90b956c81..48576dd76 100644
--- a/test/unit/versionUtils.test.js
+++ b/test/unit/versionUtils.test.js
@@ -25,6 +25,23 @@ describe('getSpecVersion', function() {
expect(specVersion).to.be.equal('3.0');
});
+ it('Should resolve as 3.0 even if the provided spec contain spaces before version from a YAML input', function() {
+ const inputData = 'openapi : 3.0.0' +
+ 'info:' +
+ ' version: 1.0.0' +
+ ' title: Sample API' +
+ ' description: A sample API to illustrate OpenAPI concepts' +
+ 'paths:' +
+ ' /list:' +
+ ' get:' +
+ ' description: Returns a list of stuff' +
+ ' responses:' +
+ ' \'200\':' +
+ ' description: Successful response',
+ specVersion = getSpecVersion({ type: stringType, data: inputData });
+ expect(specVersion).to.be.equal('3.0');
+ });
+
it('Should resolve as 3.1 the provided spec version from a YAML input', function() {
const inputData = 'openapi: 3.1.0' +
'info:' +
@@ -48,6 +65,30 @@ describe('getSpecVersion', function() {
expect(specVersion).to.be.equal('3.1');
});
+ it('Should resolve as 3.1 even if the provided spec contain spaces before version from a YAML input', function() {
+ // Below data contains tabs and spaces before version field which is considered a valid YAML
+ const inputData = 'openapi : \t"3.1.0"' +
+ 'info:' +
+ ' title: Non-oAuth Scopes example' +
+ ' version: 1.0.0' +
+ 'paths:' +
+ ' /users:' +
+ ' get:' +
+ ' security:' +
+ ' - bearerAuth:' +
+ ' - \'read:users\'' +
+ ' - \'public\'' +
+ 'components:' +
+ ' securitySchemes:' +
+ ' bearerAuth:' +
+ ' type: http' +
+ ' scheme: bearer' +
+ ' bearerFormat: jwt' +
+ ' description: \'note: non-oauth scopes are not defined at the securityScheme level\'',
+ specVersion = getSpecVersion({ type: stringType, data: inputData });
+ expect(specVersion).to.be.equal('3.1');
+ });
+
it('Should resolve as 2.0 the provided spec version from a YAML input', function() {
const inputData = 'swagger: "2.0"' +
'info:' +
@@ -74,6 +115,33 @@ describe('getSpecVersion', function() {
expect(specVersion).to.be.equal('2.0');
});
+ it('Should resolve as 2.0 even if the provided spec contain spaces before version from a YAML input', function() {
+ // Below data contains newline before version field which is considered a valid YAML
+ const inputData = 'swagger :\n "2.0"\n' +
+ 'info:' +
+ ' version: 1.0.0' +
+ ' title: Swagger Petstore' +
+ ' license:' +
+ ' name: MIT' +
+ 'host: petstore.swagger.io' +
+ 'basePath: /v1' +
+ 'schemes:' +
+ ' - http' +
+ 'consumes:' +
+ ' - application/json' +
+ 'produces:' +
+ ' - application/json' +
+ 'paths:' +
+ ' /pets:' +
+ ' get:' +
+ ' summary: List all pets' +
+ ' operationId: listPets' +
+ ' tags:' +
+ ' - pets',
+ specVersion = getSpecVersion({ type: stringType, data: inputData });
+ expect(specVersion).to.be.equal('2.0');
+ });
+
it('Should resolve as 3.0 the provided spec version from a JSON input', function() {
const inputData = {
'openapi': '3.0.0',
@@ -101,6 +169,33 @@ describe('getSpecVersion', function() {
expect(specVersion).to.be.equal('3.0');
});
+ it('Should resolve as 3.0 even if the provided spec contain spaces before version from a JSON input', function() {
+ const inputData = `{
+ 'openapi' : '3.0.0',
+ 'info': {
+ 'version': '1.0.0',
+ 'title': 'Sample API',
+ 'description': 'A sample API to illustrate OpenAPI concepts'
+ },
+ 'paths': {
+ '/users': {
+ 'get': {
+ 'security': [
+ {
+ 'bearerAuth': [
+ 'read:users',
+ 'public'
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }`,
+ specVersion = getSpecVersion({ type: stringType, data: inputData });
+ expect(specVersion).to.be.equal('3.0');
+ });
+
it('Should resolve as 3.1 the provided spec version from a JSON input', function() {
const inputData = {
'openapi': '3.1.0',
@@ -137,6 +232,43 @@ describe('getSpecVersion', function() {
expect(specVersion).to.be.equal('3.1');
});
+ it('Should resolve as 3.1 even if the provided spec contain spaces before version from a JSON input', function() {
+ // Below data contains both tab and spaces after openapi field
+ const inputData = `{
+ 'openapi' : '3.1.0',
+ 'info': {
+ 'title': 'Non-oAuth Scopes example',
+ 'version': '1.0.0'
+ },
+ 'paths': {
+ '/users': {
+ 'get': {
+ 'security': [
+ {
+ 'bearerAuth': [
+ 'read:users',
+ 'public'
+ ]
+ }
+ ]
+ }
+ }
+ },
+ 'components': {
+ 'securitySchemes': {
+ 'bearerAuth': {
+ 'type': 'http',
+ 'scheme': 'bearer',
+ 'bearerFormat': 'jwt',
+ 'description': 'note: non-oauth scopes are not defined at the securityScheme level'
+ }
+ }
+ }
+ }`,
+ specVersion = getSpecVersion({ type: stringType, data: inputData });
+ expect(specVersion).to.be.equal('3.1');
+ });
+
it('Should resolve as 2.0 the provided spec version from a JSON input', function() {
const inputData = {
'swagger': '2.0',
@@ -173,6 +305,45 @@ describe('getSpecVersion', function() {
specVersion = getSpecVersion({ type: jsonType, data: inputData });
expect(specVersion).to.be.equal('2.0');
});
+
+ it('Should resolve as 2.0 even if the provided spec contain spaces before version from a JSON input', function() {
+ // Below data contains new line before version field which is a valid json
+ const inputData = `{
+ 'swagger':
+ '2.0',
+ 'info': {
+ 'version': '1.0.0',
+ 'title': 'Swagger Petstore',
+ 'license': {
+ 'name': 'MIT'
+ }
+ },
+ 'host': 'petstore.swagger.io',
+ 'basePath': '/v1',
+ 'schemes': [
+ 'http'
+ ],
+ 'consumes': [
+ 'application/json'
+ ],
+ 'produces': [
+ 'application/json'
+ ],
+ 'paths': {
+ '/pets': {
+ 'get': {
+ 'summary': 'List all pets',
+ 'operationId': 'listPets',
+ 'tags': [
+ 'pets'
+ ]
+ }
+ }
+ }
+ }`,
+ specVersion = getSpecVersion({ type: stringType, data: inputData });
+ expect(specVersion).to.be.equal('2.0');
+ });
});
describe('filterOptionsByVersion method', function() {
@@ -314,23 +485,23 @@ describe('compareVersion method', function () {
describe('getVersionRegexBySpecificationVersion method', function () {
it('should return regex for 3.0', function () {
const result = getVersionRegexBySpecificationVersion('3.0');
- expect(result.toString()).to.equal('/openapi[\'|\"]?:\\s?[\\]?[\'|\"]?3.0/');
+ expect(result.toString()).to.equal('/openapi[\'|\"]?\\s*:\\s*[\\]?[\'|\"]?3.0/');
});
it('should return regex for 3.0.0', function () {
const result = getVersionRegexBySpecificationVersion('3.0.0');
- expect(result.toString()).to.equal('/openapi[\'|\"]?:\\s?[\\]?[\'|\"]?3.0/');
+ expect(result.toString()).to.equal('/openapi[\'|\"]?\\s*:\\s*[\\]?[\'|\"]?3.0/');
});
it('should return regex for 3.1', function () {
const result = getVersionRegexBySpecificationVersion('3.1');
- expect(result.toString()).to.equal('/openapi[\'|\"]?:\\s?[\\]?[\'|\"]?3.1/');
+ expect(result.toString()).to.equal('/openapi[\'|\"]?\\s*:\\s*[\\]?[\'|\"]?3.1/');
});
it('should return regex for 2.0', function () {
const result = getVersionRegexBySpecificationVersion('2.0');
- expect(result.toString()).to.equal('/swagger[\'|\"]?:\\s?[\\]?[\'|\"]?2.0/');
+ expect(result.toString()).to.equal('/swagger[\'|\"]?\\s*:\\s*[\\]?[\'|\"]?2.0/');
});
it('should return regex for 3.0 as default', function () {
const result = getVersionRegexBySpecificationVersion('invalid');
- expect(result.toString()).to.equal('/openapi[\'|\"]?:\\s?[\\]?[\'|\"]?3.0/');
+ expect(result.toString()).to.equal('/openapi[\'|\"]?\\s*:\\s*[\\]?[\'|\"]?3.0/');
});
});