diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0cfe457..2ace168 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [2.4.0] - 2026-05-07
+
+### Added
+- Added support for OpenAPI 3.2.
+
## [2.3.0] - 2026-03-05
### Added
diff --git a/index.js b/index.js
index 1c2346a..a378f2a 100644
--- a/index.js
+++ b/index.js
@@ -78,7 +78,9 @@ const endpointsParsed = require('./src/parser/endpoints.js')()
const authorizationTokens = []
_.forEach(endpointsParsed, function (endpointParsed, i) {
endpointsParsed[i].status = require('./src/parser/status.js')(endpointParsed.verb, endpointParsed.path)
- if (endpointParsed.verb === 'POST' || endpointParsed.verb === 'PUT' || endpointParsed.verb === 'PATCH') {
+ const standardWriteMethods = ['POST', 'PUT', 'PATCH'];
+ const hasRequestBody = globalThis.definition.paths?.[endpointParsed.path]?.[endpointParsed.verb.toLowerCase()]?.requestBody;
+ if (standardWriteMethods.includes(endpointParsed.verb) || hasRequestBody) {
endpointsParsed[i].body = require('./src/parser/'+version+'/body.js')(endpointParsed.verb, endpointParsed.path)
endpointsParsed[i].consumes = require('./src/parser/'+version+'/consumes.js')(endpointParsed.verb, endpointParsed.path)
}
diff --git a/package-lock.json b/package-lock.json
index fc4e705..4cd3e68 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "openapi2postman",
- "version": "2.2.1",
+ "version": "2.4.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "openapi2postman",
- "version": "2.2.1",
+ "version": "2.4.0",
"license": "ISC",
"dependencies": {
"js-yaml": "^4.1.0",
@@ -120,9 +120,10 @@
}
},
"node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
diff --git a/package.json b/package.json
index 9bc5297..1ccfcf3 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "openapi2postman",
- "version": "2.3.0",
+ "version": "2.4.0",
"description": "openapi2postman",
"bin": {
"o2p": "index.js"
diff --git a/readme.md b/readme.md
index d18c081..c2450dc 100644
--- a/readme.md
+++ b/readme.md
@@ -1,7 +1,7 @@
-# 🛠️ Openapi2Postman    [](https://www.npmjs.com/package/openapi2postman) [](https://www.gnu.org/licenses/lgpl-3.0)
+# 🛠️ Openapi2Postman    [](https://www.npmjs.com/package/openapi2postman) [](https://www.gnu.org/licenses/lgpl-3.0)
-**Openapi2Postman** creates automatic tests from Openapi 3.0 using postman format. Also, it creates environments files, depending of configuration.
-Those collections can be importend in postan application. The tests includes tests for 2xx, 4xx... and tests to validate output formats.
+**Openapi2Postman** creates automatic tests from OpenAPI 3.0, 3.1, and 3.2 specifications using postman format. Also, it creates environments files, depending of configuration.
+Those collections can be imported in postman application. The tests includes tests for 2xx, 4xx... and tests to validate output formats.
diff --git a/seeds/parserAuthorizationInitialOpenApi3.2.json b/seeds/parserAuthorizationInitialOpenApi3.2.json
new file mode 100644
index 0000000..f509ef4
--- /dev/null
+++ b/seeds/parserAuthorizationInitialOpenApi3.2.json
@@ -0,0 +1,290 @@
+{
+ "openapi": "3.2.0",
+ "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
+ "info": {
+ "version": "1.0.0",
+ "title": "Swagger Petstore",
+ "description": "A sample API that uses a petstore as an example to demonstrate features in the OpenAPI 3.2 specification",
+ "termsOfService": "http://swagger.io/terms/",
+ "contact": {
+ "name": "Swagger API Team",
+ "email": "apiteam@swagger.io",
+ "url": "http://swagger.io"
+ },
+ "license": {
+ "name": "Apache 2.0",
+ "url": "https://www.apache.org/licenses/LICENSE-2.0.html"
+ }
+ },
+ "servers": [
+ {
+ "url": "http://petstore.swagger.io/api"
+ }
+ ],
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "paths": {
+ "/pets": {
+ "get": {
+ "security": [
+ {
+ "OAuth2": ["admin"]
+ }
+ ],
+ "description": "Returns all pets from the system that the user has access to",
+ "operationId": "findPets",
+ "parameters": [
+ {
+ "name": "tags",
+ "in": "query",
+ "description": "tags to filter by",
+ "required": false,
+ "style": "form",
+ "explode": true,
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "description": "maximum number of results to return",
+ "required": false,
+ "schema": {
+ "type": ["integer", "null"],
+ "format": "int32",
+ "minimum": 1
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "pet response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Pet"
+ }
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "unexpected error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "description": "Creates a new pet in the store. Duplicates are allowed",
+ "operationId": "addPet",
+ "requestBody": {
+ "description": "Pet to add to the store",
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/NewPet"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "pet response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Pet"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "unexpected error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/pets/{id}": {
+ "get": {
+ "description": "Returns a pet based on a single ID",
+ "operationId": "findPetById",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/PetId"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "pet response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Pet"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "pet not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "description": "Deletes a single pet based on the ID supplied",
+ "operationId": "deletePet",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/PetId"
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "pet deleted"
+ },
+ "default": {
+ "description": "unexpected error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "parameters": {
+ "PetId": {
+ "name": "id",
+ "in": "path",
+ "description": "ID of pet",
+ "required": true,
+ "schema": {
+ "type": "integer",
+ "format": "int64",
+ "minimum": 1
+ }
+ }
+ },
+ "securitySchemes": {
+ "BasicAuth": {
+ "type": "http",
+ "scheme": "basic"
+ },
+ "BearerAuth": {
+ "type": "http",
+ "scheme": "bearer"
+ },
+ "ApiKeyAuth": {
+ "type": "apiKey",
+ "in": "header",
+ "name": "X-API-Key"
+ },
+ "OpenID": {
+ "type": "openIdConnect",
+ "openIdConnectUrl": "https://example.com/.well-known/openid-configuration"
+ },
+ "OAuth2": {
+ "type": "oauth2",
+ "flows": {
+ "authorizationCode": {
+ "authorizationUrl": "https://example.com/oauth/authorize",
+ "tokenUrl": "https://example.com/oauth/token",
+ "scopes": {
+ "read": "Grants read access",
+ "write": "Grants write access",
+ "admin": "Grants access to admin operations"
+ }
+ }
+ }
+ }
+ },
+ "schemas": {
+ "Pet": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/NewPet"
+ },
+ {
+ "type": "object",
+ "required": ["id"],
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
+ }
+ },
+ "unevaluatedProperties": false
+ }
+ ]
+ },
+ "NewPet": {
+ "type": "object",
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "tag": {
+ "type": ["string", "null"],
+ "examples": ["dog", "cat", null]
+ },
+ "status": {
+ "type": "string",
+ "const": "available"
+ }
+ },
+ "unevaluatedProperties": false
+ },
+ "Error": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "type": "object",
+ "required": ["code", "message"],
+ "properties": {
+ "code": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "message": {
+ "type": "string"
+ }
+ },
+ "unevaluatedProperties": false
+ }
+ }
+ }
+}
diff --git a/seeds/parserBodyItemSchema3.2.json b/seeds/parserBodyItemSchema3.2.json
new file mode 100644
index 0000000..b3c9290
--- /dev/null
+++ b/seeds/parserBodyItemSchema3.2.json
@@ -0,0 +1,30 @@
+{
+ "openapi": "3.2.0",
+ "info": { "version": "1.0.0", "title": "Streaming API" },
+ "servers": [{ "url": "https://api.example.com/v1" }],
+ "paths": {
+ "/events": {
+ "get": {
+ "operationId": "streamEvents",
+ "responses": {
+ "200": {
+ "description": "Server-sent event stream",
+ "content": {
+ "application/jsonl": {
+ "itemSchema": {
+ "type": "object",
+ "required": ["id", "type"],
+ "properties": {
+ "id": { "type": "integer" },
+ "type": { "type": "string" }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": { "schemas": {} }
+}
diff --git a/seeds/parserBodyItemSchemaResult3.2.json b/seeds/parserBodyItemSchemaResult3.2.json
new file mode 100644
index 0000000..a45d3ca
--- /dev/null
+++ b/seeds/parserBodyItemSchemaResult3.2.json
@@ -0,0 +1,10 @@
+{
+ "200": {
+ "type": "object",
+ "required": ["id", "type"],
+ "properties": {
+ "id": { "type": "integer" },
+ "type": { "type": "string" }
+ }
+ }
+}
diff --git a/seeds/parserEndpointsAdditionalOps3.2.json b/seeds/parserEndpointsAdditionalOps3.2.json
new file mode 100644
index 0000000..b7fc563
--- /dev/null
+++ b/seeds/parserEndpointsAdditionalOps3.2.json
@@ -0,0 +1,24 @@
+{
+ "openapi": "3.2.0",
+ "info": { "version": "1.0.0", "title": "Additional Operations API" },
+ "servers": [{ "url": "https://api.example.com/v1" }],
+ "paths": {
+ "/pets": {
+ "get": {
+ "operationId": "listPets",
+ "responses": {
+ "200": { "description": "A list of pets" }
+ }
+ },
+ "additionalOperations": {
+ "SEARCH": {
+ "operationId": "searchPets",
+ "responses": {
+ "200": { "description": "Search results" }
+ }
+ }
+ }
+ }
+ },
+ "components": { "schemas": {} }
+}
diff --git a/seeds/parserEndpointsCustomMethod3.2.json b/seeds/parserEndpointsCustomMethod3.2.json
new file mode 100644
index 0000000..3a57683
--- /dev/null
+++ b/seeds/parserEndpointsCustomMethod3.2.json
@@ -0,0 +1,22 @@
+{
+ "openapi": "3.2.0",
+ "info": { "version": "1.0.0", "title": "Custom Methods API" },
+ "servers": [{ "url": "https://api.example.com/v1" }],
+ "paths": {
+ "/pets": {
+ "get": {
+ "operationId": "listPets",
+ "responses": {
+ "200": { "description": "A list of pets" }
+ }
+ },
+ "search": {
+ "operationId": "searchPets",
+ "responses": {
+ "200": { "description": "Search results" }
+ }
+ }
+ }
+ },
+ "components": { "schemas": {} }
+}
diff --git a/seeds/parserEndpointsCustomMethodResult3.2.json b/seeds/parserEndpointsCustomMethodResult3.2.json
new file mode 100644
index 0000000..bbfbed9
--- /dev/null
+++ b/seeds/parserEndpointsCustomMethodResult3.2.json
@@ -0,0 +1,4 @@
+[
+ { "verb": "GET", "path": "/pets" },
+ { "verb": "SEARCH", "path": "/pets" }
+]
diff --git a/seeds/parserInitialGoodOpenApi3.2.0.json b/seeds/parserInitialGoodOpenApi3.2.0.json
new file mode 100644
index 0000000..abfc384
--- /dev/null
+++ b/seeds/parserInitialGoodOpenApi3.2.0.json
@@ -0,0 +1,178 @@
+{
+ "openapi":"3.2.0",
+ "info":{
+ "version":"1.0.0",
+ "title":"Swagger Petstore",
+ "license":{
+ "name":"MIT"
+ }
+ },
+ "servers":[
+ {
+ "url":"https://petstore.swagger.io/v1"
+ }
+ ],
+ "paths":{
+ "/pets":{
+ "get":{
+ "summary":"List all pets",
+ "operationId":"listPets",
+ "tags":[
+ "pets"
+ ],
+ "parameters":[
+ {
+ "name":"limit",
+ "in":"query",
+ "description":"How many items to return at one time (max 100)",
+ "required":false,
+ "schema":{
+ "type":"integer",
+ "format":"int32"
+ }
+ }
+ ],
+ "responses":{
+ "200":{
+ "description":"A paged array of pets",
+ "headers":{
+ "x-next":{
+ "description":"A link to the next page of responses",
+ "schema":{
+ "type":"string"
+ }
+ }
+ },
+ "content":{
+ "application/json":{
+ "schema":{
+ "$ref":"#/components/schemas/Pets"
+ }
+ }
+ }
+ },
+ "default":{
+ "description":"unexpected error",
+ "content":{
+ "application/json":{
+ "schema":{
+ "$ref":"#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post":{
+ "summary":"Create a pet",
+ "operationId":"createPets",
+ "tags":[
+ "pets"
+ ],
+ "responses":{
+ "201":{
+ "description":"Null response"
+ },
+ "default":{
+ "description":"unexpected error",
+ "content":{
+ "application/json":{
+ "schema":{
+ "$ref":"#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/pets/{petId}":{
+ "get":{
+ "summary":"Info for a specific pet",
+ "operationId":"showPetById",
+ "tags":[
+ "pets"
+ ],
+ "parameters":[
+ {
+ "name":"petId",
+ "in":"path",
+ "required":true,
+ "description":"The id of the pet to retrieve",
+ "schema":{
+ "type":"string",
+ "example":"asdf"
+ }
+ }
+ ],
+ "responses":{
+ "200":{
+ "description":"Expected response to a valid request",
+ "content":{
+ "application/json":{
+ "schema":{
+ "$ref":"#/components/schemas/Pet"
+ }
+ }
+ }
+ },
+ "default":{
+ "description":"unexpected error",
+ "content":{
+ "application/json":{
+ "schema":{
+ "$ref":"#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components":{
+ "schemas":{
+ "Pet":{
+ "type":"object",
+ "required":[
+ "id",
+ "name"
+ ],
+ "properties":{
+ "id":{
+ "type":"integer",
+ "format":"int64"
+ },
+ "name":{
+ "type":"string"
+ },
+ "tag":{
+ "type":"string"
+ }
+ }
+ },
+ "Pets":{
+ "type":"array",
+ "items":{
+ "$ref":"#/components/schemas/Pet"
+ }
+ },
+ "Error":{
+ "type":"object",
+ "required":[
+ "code",
+ "message"
+ ],
+ "properties":{
+ "code":{
+ "type":"integer",
+ "format":"int32"
+ },
+ "message":{
+ "type":"string"
+ }
+ }
+ }
+ }
+ }
+ }
diff --git a/seeds/parserInitialGoodOpenApi3.2.json b/seeds/parserInitialGoodOpenApi3.2.json
new file mode 100644
index 0000000..abfc384
--- /dev/null
+++ b/seeds/parserInitialGoodOpenApi3.2.json
@@ -0,0 +1,178 @@
+{
+ "openapi":"3.2.0",
+ "info":{
+ "version":"1.0.0",
+ "title":"Swagger Petstore",
+ "license":{
+ "name":"MIT"
+ }
+ },
+ "servers":[
+ {
+ "url":"https://petstore.swagger.io/v1"
+ }
+ ],
+ "paths":{
+ "/pets":{
+ "get":{
+ "summary":"List all pets",
+ "operationId":"listPets",
+ "tags":[
+ "pets"
+ ],
+ "parameters":[
+ {
+ "name":"limit",
+ "in":"query",
+ "description":"How many items to return at one time (max 100)",
+ "required":false,
+ "schema":{
+ "type":"integer",
+ "format":"int32"
+ }
+ }
+ ],
+ "responses":{
+ "200":{
+ "description":"A paged array of pets",
+ "headers":{
+ "x-next":{
+ "description":"A link to the next page of responses",
+ "schema":{
+ "type":"string"
+ }
+ }
+ },
+ "content":{
+ "application/json":{
+ "schema":{
+ "$ref":"#/components/schemas/Pets"
+ }
+ }
+ }
+ },
+ "default":{
+ "description":"unexpected error",
+ "content":{
+ "application/json":{
+ "schema":{
+ "$ref":"#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post":{
+ "summary":"Create a pet",
+ "operationId":"createPets",
+ "tags":[
+ "pets"
+ ],
+ "responses":{
+ "201":{
+ "description":"Null response"
+ },
+ "default":{
+ "description":"unexpected error",
+ "content":{
+ "application/json":{
+ "schema":{
+ "$ref":"#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/pets/{petId}":{
+ "get":{
+ "summary":"Info for a specific pet",
+ "operationId":"showPetById",
+ "tags":[
+ "pets"
+ ],
+ "parameters":[
+ {
+ "name":"petId",
+ "in":"path",
+ "required":true,
+ "description":"The id of the pet to retrieve",
+ "schema":{
+ "type":"string",
+ "example":"asdf"
+ }
+ }
+ ],
+ "responses":{
+ "200":{
+ "description":"Expected response to a valid request",
+ "content":{
+ "application/json":{
+ "schema":{
+ "$ref":"#/components/schemas/Pet"
+ }
+ }
+ }
+ },
+ "default":{
+ "description":"unexpected error",
+ "content":{
+ "application/json":{
+ "schema":{
+ "$ref":"#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components":{
+ "schemas":{
+ "Pet":{
+ "type":"object",
+ "required":[
+ "id",
+ "name"
+ ],
+ "properties":{
+ "id":{
+ "type":"integer",
+ "format":"int64"
+ },
+ "name":{
+ "type":"string"
+ },
+ "tag":{
+ "type":"string"
+ }
+ }
+ },
+ "Pets":{
+ "type":"array",
+ "items":{
+ "$ref":"#/components/schemas/Pet"
+ }
+ },
+ "Error":{
+ "type":"object",
+ "required":[
+ "code",
+ "message"
+ ],
+ "properties":{
+ "code":{
+ "type":"integer",
+ "format":"int32"
+ },
+ "message":{
+ "type":"string"
+ }
+ }
+ }
+ }
+ }
+ }
diff --git a/seeds/parserInitialGoodOpenApiExpanded3.2.json b/seeds/parserInitialGoodOpenApiExpanded3.2.json
new file mode 100644
index 0000000..8ee6005
--- /dev/null
+++ b/seeds/parserInitialGoodOpenApiExpanded3.2.json
@@ -0,0 +1,215 @@
+{
+ "openapi": "3.2.0",
+ "jsonSchemaDialect": "https://spec.openapis.org/oas/3.2/dialect/base",
+ "info": {
+ "version": "1.0.0",
+ "title": "Swagger Petstore"
+ },
+ "servers": [
+ {
+ "url": "http://petstore.swagger.io/api"
+ }
+ ],
+ "paths": {
+ "/pets": {
+ "get": {
+ "operationId": "findPets",
+ "parameters": [
+ {
+ "name": "tags",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "required": true,
+ "schema": {
+ "type": "integer",
+ "format": "int32"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "pet response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Pet"
+ }
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "unexpected error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "operationId": "addPet",
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/NewPet"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "pet response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Pet"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "unexpected error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/pets/{id}": {
+ "get": {
+ "operationId": "findPetById",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "integer",
+ "format": "int64"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "pet response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Pet"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "unexpected error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "operationId": "deletePet",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "integer",
+ "format": "int64"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "pet deleted"
+ },
+ "500": {
+ "description": "unexpected error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "Pet": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/NewPet"
+ },
+ {
+ "type": "object",
+ "required": ["id"],
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
+ }
+ }
+ }
+ ]
+ },
+ "NewPet": {
+ "type": "object",
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ }
+ }
+ },
+ "Error": {
+ "type": "object",
+ "required": ["code", "message"],
+ "properties": {
+ "code": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "message": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/seeds/parserMicroksinitialGood3.2.json b/seeds/parserMicroksinitialGood3.2.json
new file mode 100644
index 0000000..f5123bc
--- /dev/null
+++ b/seeds/parserMicroksinitialGood3.2.json
@@ -0,0 +1,117 @@
+{
+ "openapi": "3.2.0",
+ "info": {
+ "title": "Swagger Petstore 2.0",
+ "description": "This is a sample server Petstore server.",
+ "termsOfService": "http://swagger.io/terms/",
+ "contact": {
+ "email": "apiteam@swagger.io"
+ },
+ "license": {
+ "name": "Apache 2.0",
+ "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
+ },
+ "version": "1.0.0"
+ },
+ "servers": [
+ {
+ "url": "https://petstore.swagger.io/v2"
+ },
+ {
+ "url": "http://petstore.swagger.io/v2"
+ }
+ ],
+ "paths": {
+ "/user": {
+ "post": {
+ "tags": ["user"],
+ "summary": "Create user",
+ "operationId": "createUser",
+ "requestBody": {
+ "required": true,
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/User"
+ }
+ }
+ }
+ },
+ "responses": {
+ "default": {
+ "description": "successful operation"
+ }
+ }
+ }
+ },
+ "/user/{username}": {
+ "get": {
+ "tags": ["user"],
+ "summary": "Get user by user name",
+ "operationId": "getUserByName",
+ "parameters": [
+ {
+ "name": "username",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/User"
+ }
+ }
+ }
+ }
+ },
+ "x-microcks-operation": {
+ "delay": 100,
+ "dispatcher": "SCRIPT",
+ "dispatcherRules": "def headers = mockRequest.getRequestHeaders(); if (headers.hasValues(\"X-Microcks-Response-Name\")) { return headers.get(\"X-Microcks-Response-Name\", \"null\") }"
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "User": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "username": {
+ "type": "string"
+ },
+ "firstName": {
+ "type": "string"
+ },
+ "lastName": {
+ "type": "string"
+ },
+ "email": {
+ "type": "string"
+ },
+ "password": {
+ "type": "string"
+ },
+ "phone": {
+ "type": "string"
+ },
+ "userStatus": {
+ "type": "integer",
+ "format": "int32"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/seeds/parserQueryParamsQuerystring3.2.json b/seeds/parserQueryParamsQuerystring3.2.json
new file mode 100644
index 0000000..2ba0ac4
--- /dev/null
+++ b/seeds/parserQueryParamsQuerystring3.2.json
@@ -0,0 +1,25 @@
+{
+ "openapi": "3.2.0",
+ "info": { "version": "1.0.0", "title": "Querystring Param API" },
+ "servers": [{ "url": "https://api.example.com/v1" }],
+ "paths": {
+ "/search": {
+ "get": {
+ "operationId": "search",
+ "parameters": [
+ {
+ "name": "q",
+ "in": "querystring",
+ "description": "Full query string to pass as a single value",
+ "required": false,
+ "schema": { "type": "string" }
+ }
+ ],
+ "responses": {
+ "200": { "description": "Search results" }
+ }
+ }
+ }
+ },
+ "components": { "schemas": {} }
+}
diff --git a/seeds/parserSummaryOpenApi3.2.json b/seeds/parserSummaryOpenApi3.2.json
new file mode 100644
index 0000000..dd5fc8b
--- /dev/null
+++ b/seeds/parserSummaryOpenApi3.2.json
@@ -0,0 +1,117 @@
+{
+ "openapi": "3.2.0",
+ "jsonSchemaDialect": "https://spec.openapis.org/oas/3.2/dialect/base",
+ "info": {
+ "version": "1.0.0",
+ "title": "Swagger Petstore",
+ "description": "A sample API that uses a petstore as an example to demonstrate features in the OpenAPI 3.2 specification",
+ "termsOfService": "http://swagger.io/terms/",
+ "contact": {
+ "name": "Swagger API Team",
+ "email": "apiteam@swagger.io",
+ "url": "http://swagger.io"
+ },
+ "license": {
+ "name": "Apache 2.0",
+ "identifier": "Apache-2.0"
+ }
+ },
+ "servers": [
+ {
+ "url": "http://petstore.swagger.io/api"
+ }
+ ],
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "paths": {
+ "/pets": {
+ "get": {
+ "summary": "Pets list",
+ "operationId": "findPets",
+ "responses": {
+ "200": {
+ "description": "pet response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Pet"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "summary": "Create pet",
+ "operationId": "addPet",
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/NewPet"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "pet response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Pet"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "securitySchemes": {
+ "ApiKeyAuth": {
+ "type": "apiKey",
+ "in": "header",
+ "name": "X-API-Key"
+ }
+ },
+ "schemas": {
+ "Pet": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/NewPet"
+ },
+ {
+ "type": "object",
+ "required": ["id"],
+ "properties": {
+ "id": {
+ "type": "integer"
+ }
+ }
+ }
+ ]
+ },
+ "NewPet": {
+ "type": "object",
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": ["string", "null"]
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/parser/endpoints.js b/src/parser/endpoints.js
index 2563283..eb4880b 100644
--- a/src/parser/endpoints.js
+++ b/src/parser/endpoints.js
@@ -18,10 +18,12 @@ module.exports = function () {
const items = [];
_.forEach(globalThis.definition.paths, function (pathInfo, path) {
_.forEach(pathInfo, function (verbInfo, verb) {
- items.push({
- 'verb': _.toUpper(verb),
- 'path': path
- });
+ if (_.isObject(verbInfo) && verbInfo.responses) {
+ items.push({
+ 'verb': _.toUpper(verb),
+ 'path': path
+ });
+ }
});
});
return items;
diff --git a/src/parser/openapi3/body.js b/src/parser/openapi3/body.js
index db696f6..920630b 100644
--- a/src/parser/openapi3/body.js
+++ b/src/parser/openapi3/body.js
@@ -5,6 +5,14 @@
const _ = require('lodash')
const checkCircularReferences = require('../../utils/circularRef.js');
+const STREAMING_CONTENT_TYPES = [
+ 'application/jsonl',
+ 'application/ndjson',
+ 'application/x-ndjson',
+ 'text/event-stream',
+ 'multipart/mixed',
+]
+
module.exports = function () {
const MAX_DEPTH_LEVEL = 20;
@@ -40,24 +48,27 @@ module.exports = function () {
while (!properContent && index < contentsArray.length) {
const mediaType = body.content[contentsArray[index]];
- if (!mediaType.schema) {
+ const effectiveSchema = mediaType.schema || mediaType.itemSchema;
+
+ if (!effectiveSchema) {
if (contentsArray[index] === 'application/octet-stream') {
return {
type: 'string',
format: 'binary'
};
}
+ index++;
continue;
}
- const withoutRefs = replaceRefs(mediaType.schema, 1);
+ const withoutRefs = replaceRefs(effectiveSchema, 1);
switch (contentsArray[index]) {
case 'application/x-www-form-urlencoded':
schema = replaceAllOfs(withoutRefs);
properContent = true;
break;
case 'multipart/form-data':
- schema = replaceAllOfs(body.content[contentsArray[index]].schema);
+ schema = replaceAllOfs(body.content[contentsArray[index]].schema || body.content[contentsArray[index]].itemSchema);
properContent = true;
break;
default:
@@ -70,9 +81,10 @@ module.exports = function () {
if (!properContent && contentsArray.length > 0) {
const firstContentType = contentsArray[0];
const mediaType = body.content[firstContentType];
+ const effectiveSchema = mediaType?.schema || mediaType?.itemSchema;
- if (mediaType?.schema) {
- const withoutRefs = replaceRefs(mediaType.schema, 1);
+ if (effectiveSchema) {
+ const withoutRefs = replaceRefs(effectiveSchema, 1);
return replaceAllOfs(withoutRefs);
}
}
@@ -85,8 +97,22 @@ module.exports = function () {
}
const bodyResponses = {}
_.forEach(endpoint['responses'], function (response, status) {
+ let schema = null
+
if (response?.content?.['application/json']?.schema) {
- const withOutRefs = replaceRefs(response.content['application/json'].schema, 1)
+ schema = response.content['application/json'].schema
+ } else if (response?.content) {
+ for (const streamType of STREAMING_CONTENT_TYPES) {
+ const mt = response.content[streamType]
+ if (mt) {
+ schema = mt.schema || mt.itemSchema
+ if (schema) break
+ }
+ }
+ }
+
+ if (schema) {
+ const withOutRefs = replaceRefs(schema, 1)
bodyResponses[status] = replaceAllOfs(withOutRefs)
if (bodyResponses[status].hasOwnProperty('required')) {
const requiredWtihoutDuplicates = bodyResponses[status].required.filter((value, index, arr) => {
@@ -241,4 +267,4 @@ module.exports = function () {
return result
}
-}()
\ No newline at end of file
+}()
diff --git a/src/parser/openapi3/queryParams.js b/src/parser/openapi3/queryParams.js
index 650c2df..647f641 100644
--- a/src/parser/openapi3/queryParams.js
+++ b/src/parser/openapi3/queryParams.js
@@ -15,9 +15,9 @@ module.exports = function() {
const param = queryParam.schema ? queryParam : getContentProperty(queryParam);
const obj = {
- name: queryParam.name,
- type: param.schema.type,
- required : queryParam.required,
+ name: queryParam.name,
+ type: param.schema.type,
+ required : queryParam.required,
};
const example = getExamples(param);
@@ -29,6 +29,20 @@ module.exports = function() {
result.push(obj);
});
+ const queryStringParams = _.filter(parameters, ['in', 'querystring'])
+ _.forEach(queryStringParams, function(queryParam) {
+ const obj = {
+ name: queryParam.name,
+ type: queryParam.schema?.type || 'string',
+ required: queryParam.required,
+ }
+ const example = getExamples(queryParam)
+ if (example !== undefined && example !== null) {
+ obj.example = example
+ }
+ result.push(obj)
+ })
+
return result
};
diff --git a/src/parser/openapi3/refs.js b/src/parser/openapi3/refs.js
index 8029f0e..26ecd3d 100644
--- a/src/parser/openapi3/refs.js
+++ b/src/parser/openapi3/refs.js
@@ -7,12 +7,18 @@ function eachRecursive(obj) {
if (typeof obj[k] == "object" && obj[k] !== null) {
eachRecursive(obj[k]);
} else if (k == '$ref') {
+ const siblings = {}
+ for (const sib of Object.keys(obj)) {
+ if (sib !== '$ref') {
+ siblings[sib] = obj[sib]
+ }
+ }
let property = obj[k]
property = property.replace('#/', '')
let propertiesArray = property.split('/')
let refObject = findObject(globalThis.definition, propertiesArray)
delete obj[k]
- Object.assign(obj, refObject)
+ Object.assign(obj, refObject, siblings)
}
}
}
@@ -26,9 +32,23 @@ function findObject(obj, propertiesArray) {
return findObject(obj[property], propertiesArray)
}
+function liftAdditionalOperations() {
+ if (!globalThis.definition.paths) return
+ for (const path in globalThis.definition.paths) {
+ const pathItem = globalThis.definition.paths[path]
+ if (pathItem && typeof pathItem.additionalOperations === 'object' && pathItem.additionalOperations !== null) {
+ for (const method in pathItem.additionalOperations) {
+ pathItem[method.toLowerCase()] = pathItem.additionalOperations[method]
+ }
+ delete pathItem.additionalOperations
+ }
+ }
+}
+
module.exports = function() {
return function get() {
eachRecursive(globalThis.definition)
+ liftAdditionalOperations()
return globalThis.definition
}
}()
\ No newline at end of file
diff --git a/src/parser/openapiAuthorizationDefinition.js b/src/parser/openapiAuthorizationDefinition.js
index a8d2be6..3276ccb 100644
--- a/src/parser/openapiAuthorizationDefinition.js
+++ b/src/parser/openapiAuthorizationDefinition.js
@@ -4,6 +4,7 @@
const _ = require('lodash');
+const FLOW_PRIORITY = ['authorizationCode', 'clientCredentials', 'password', 'deviceAuthorization', 'implicit']
module.exports = function() {
@@ -13,8 +14,9 @@ module.exports = function() {
definition = oAuthDefinition[i];
}
const data = parseUrl(definition.flows)
- const authKey = _.keys(global.definition.security[0])[0]
- return generateDefinition(data,authKey)
+ if (!data) return null
+ const authKey = _.keys(globalThis.definition.security[0])[0]
+ return generateDefinition(data,authKey)
}
function generateDefinition(data,auth){
@@ -88,19 +90,32 @@ module.exports = function() {
}
function parseUrl(flows) {
- let getTokenUrl
- for (const i in flows) {
- getTokenUrl = flows[i];
+ let targetFlow = null
+ for (const flowName of FLOW_PRIORITY) {
+ if (flows[flowName]?.tokenUrl) {
+ targetFlow = flows[flowName]
+ break
+ }
}
- const urlObject = new URL(getTokenUrl.tokenUrl);
+ if (!targetFlow) {
+ for (const name in flows) {
+ if (flows[name]?.tokenUrl) {
+ targetFlow = flows[name]
+ break
+ }
+ }
+ }
+ if (!targetFlow?.tokenUrl) return null
+
+ const urlObject = new URL(targetFlow.tokenUrl);
const host = `${urlObject.protocol}//${urlObject.host}`;
- const path = urlObject.pathname.split('/').filter(segment => segment);
+ const path = urlObject.pathname.split('/').filter(Boolean);
return {
- raw: getTokenUrl.tokenUrl,
+ raw: targetFlow.tokenUrl,
host: host,
path: path
};
-}
+ }
}()
\ No newline at end of file
diff --git a/src/parser/version.js b/src/parser/version.js
index 534bd7f..0980e69 100644
--- a/src/parser/version.js
+++ b/src/parser/version.js
@@ -3,17 +3,18 @@
'use strict'
module.exports = function() {
-
+
return function get(){
const versions = {
swagger : ['2.0', '2.0.0'],
openapi3 : ['3.0', '3.0.0', '3.0.1','3.0.2', '3.0.3'],
- openapi31 : ['3.1', '3.1.0', '3.1.1', '3.1.2']
+ openapi31 : ['3.1', '3.1.0', '3.1.1', '3.1.2'],
+ openapi32 : ['3.2', '3.2.0']
}
if (versions.swagger.includes(globalThis.definition.swagger)) {
return 'swagger2'
- } else if (versions.openapi3.includes(globalThis.definition.openapi) || versions.openapi31.includes(globalThis.definition.openapi)) {
+ } else if (versions.openapi3.includes(globalThis.definition.openapi) || versions.openapi31.includes(globalThis.definition.openapi) || versions.openapi32.includes(globalThis.definition.openapi)) {
return 'openapi3'
} else {
require('../utils/error.js')('Specification is not supported')
diff --git a/test/parser-authorization.js b/test/parser-authorization.js
index 6c81a19..19e8505 100644
--- a/test/parser-authorization.js
+++ b/test/parser-authorization.js
@@ -23,4 +23,7 @@ describe('parser-authorization', () => {
checkAuth('auth general oa3.1', 'parserAuthorizationInitialOpenApi3.1.json','POST', '/pets', 'ApiKeyAuth');
checkAuth('auth endpoint oa3.1', 'parserAuthorizationInitialOpenApi3.1.json','GET', '/pets', 'OAuth2');
+ checkAuth('auth general oa3.2', 'parserAuthorizationInitialOpenApi3.2.json','POST', '/pets', 'ApiKeyAuth');
+ checkAuth('auth endpoint oa3.2', 'parserAuthorizationInitialOpenApi3.2.json','GET', '/pets', 'OAuth2');
+
});
\ No newline at end of file
diff --git a/test/parser-body.js b/test/parser-body.js
index 026d338..11c8b37 100644
--- a/test/parser-body.js
+++ b/test/parser-body.js
@@ -49,4 +49,14 @@ describe('parser-body', () => {
checkBody('body allof loop swagger2','swagger2','parserBodyAllofLoopInitial.json','POST','/apple',false,'parserInitialGoodResultAllOfLoop.json');
checkBody('body allof string swagger2','swagger2','parserBodyAllofString.json','POST','/apple',false,'parserInitialGoodResultAllOfString.json');
+
+ checkBody('body void request openapi3.2','openapi3','parserInitialGoodOpenApi3.2.json','GET','/pets',false,null);
+
+ checkBody('body fill request openapi3.2','openapi3','parserInitialGoodOpenApiExpanded3.2.json','POST','/pets',false,'parserInitialGoodResultPetRequest.json');
+
+ checkBody('body items,ref and allof response openapi3.2','openapi3','parserInitialGoodOpenApiExpanded3.2.json','GET','/pets',true,'parserInitialGoodResultRespArray.json');
+
+ checkBody('body ref and allof response openapi3.2','openapi3','parserInitialGoodOpenApiExpanded3.2.json','POST','/pets',true,'parserInitialGoodResultRespObject.json');
+
+ checkBody('body streaming itemSchema response openapi3.2','openapi3','parserBodyItemSchema3.2.json','GET','/events',true,'parserBodyItemSchemaResult3.2.json');
});
\ No newline at end of file
diff --git a/test/parser-consumes.js b/test/parser-consumes.js
index 769d1ea..e5bd5db 100644
--- a/test/parser-consumes.js
+++ b/test/parser-consumes.js
@@ -1,6 +1,6 @@
/** Part of APIAddicts. See LICENSE fileor full copyright and licensing details. Supported by Madrid Digital and CloudAPPi **/
-const assert = require('assert')
+const assert = require('node:assert')
describe('parser-consumes', () => {
@@ -36,4 +36,12 @@ describe('parser-consumes', () => {
assert.equal(consumes, 'application/json');
})
+ it('specifies openapi3.2', () => {
+
+ globalThis.definition = require('../seeds/parserInitialGoodOpenApiExpanded3.2.json');
+
+ const consumes = require('../src/parser/openapi3/consumes.js')('POST','/pets');
+ assert.equal(consumes, 'application/json');
+ })
+
})
\ No newline at end of file
diff --git a/test/parser-endpoints.js b/test/parser-endpoints.js
index 7085240..7712f02 100644
--- a/test/parser-endpoints.js
+++ b/test/parser-endpoints.js
@@ -44,4 +44,8 @@ describe('parser-endpoints', () => {
checkEndpoints('endpoints good openapi3.1', 'parserInitialGoodOpenApi3.1.json', 'parserEndpointsGoodOpenApi3Result.json');
+ checkEndpoints('endpoints good openapi3.2', 'parserInitialGoodOpenApi3.2.json', 'parserEndpointsGoodOpenApi3Result.json');
+
+ checkEndpoints('endpoints openapi3.2 additionalOperations lifted to path level', 'parserEndpointsCustomMethod3.2.json', 'parserEndpointsCustomMethodResult3.2.json');
+
});
\ No newline at end of file
diff --git a/test/parser-microcks.js b/test/parser-microcks.js
index edf57ce..313edc9 100644
--- a/test/parser-microcks.js
+++ b/test/parser-microcks.js
@@ -1,6 +1,6 @@
/** Part of APIAddicts. See LICENSE fileor full copyright and licensing details. Supported by Madrid Digital and CloudAPPi **/
-const assert = require('assert')
+const assert = require('node:assert')
describe('parser-microcks', () => {
@@ -38,4 +38,11 @@ describe('parser-microcks', () => {
assert.equal(microcks, true);
})
+ it('specifies openapi3.2', () => {
+
+ globalThis.definition = require('../seeds/parserMicroksinitialGood3.2.json');
+ const microcks = require('../src/parser/openapi3/microcks.js')('GET','/user/{username}');
+ assert.equal(microcks, true);
+ })
+
})
diff --git a/test/parser-pathParameters.js b/test/parser-pathParameters.js
index 5a0dbee..691b38a 100644
--- a/test/parser-pathParameters.js
+++ b/test/parser-pathParameters.js
@@ -1,6 +1,6 @@
/** Part of APIAddicts. See LICENSE fileor full copyright and licensing details. Supported by Madrid Digital and CloudAPPi **/
-const assert = require('assert');
+const assert = require('node:assert');
describe('parser-pathParameters', () => {
@@ -28,4 +28,12 @@ describe('parser-pathParameters', () => {
assert.deepStrictEqual(status, [ { name: 'petId', type: 'string', example: 'asdf' } ])
})
+ it('good openapi3.2', () => {
+
+ globalThis.definition = require('../seeds/parserInitialGoodOpenApi3.2.json')
+
+ const status = require('../src/parser/openapi3/pathParameters.js')('GET','/pets/{petId}')
+ assert.deepStrictEqual(status, [ { name: 'petId', type: 'string', example: 'asdf' } ])
+ })
+
})
\ No newline at end of file
diff --git a/test/parser-queryParams.js b/test/parser-queryParams.js
index f38fc2f..0c7dcb6 100644
--- a/test/parser-queryParams.js
+++ b/test/parser-queryParams.js
@@ -1,6 +1,6 @@
/** Part of APIAddicts. See LICENSE fileor full copyright and licensing details. Supported by Madrid Digital and CloudAPPi **/
-const assert = require('assert');
+const assert = require('node:assert');
describe('parser-queryParams', () => {
@@ -29,4 +29,11 @@ describe('parser-queryParams', () => {
testQuery('queryParams fill openapi3.1', 'openapi3', 'parserInitialGoodOpenApiExpanded3.1.json', 'GET', '/pets', results.tagsLimit(true));
testQuery('queryParams void openapi3.1', 'openapi3', 'parserInitialGoodOpenApiExpanded3.1.json', 'POST', '/pets', results.empty);
+ testQuery('queryParams fill openapi3.2', 'openapi3', 'parserInitialGoodOpenApiExpanded3.2.json', 'GET', '/pets', results.tagsLimit(true));
+ testQuery('queryParams void openapi3.2', 'openapi3', 'parserInitialGoodOpenApiExpanded3.2.json', 'POST', '/pets', results.empty);
+
+ testQuery('queryParams querystring openapi3.2', 'openapi3', 'parserQueryParamsQuerystring3.2.json', 'GET', '/search', [
+ { name: 'q', type: 'string', required: false }
+ ]);
+
});
\ No newline at end of file
diff --git a/test/parser-schemaHostBasePath.js b/test/parser-schemaHostBasePath.js
index 073aad3..759c701 100644
--- a/test/parser-schemaHostBasePath.js
+++ b/test/parser-schemaHostBasePath.js
@@ -1,30 +1,26 @@
/** Part of APIAddicts. See LICENSE fileor full copyright and licensing details. Supported by Madrid Digital and CloudAPPi **/
-const assert = require('assert');
+const assert = require('node:assert');
+
+const openapi3Cases = [
+ { version: '3.0', seed: '../seeds/parserInitialGoodOpenApi3.json', host: 'https://petstore.swagger.io', basePath: '/v1' },
+ { version: '3.1', seed: '../seeds/parserInitialGoodOpenApi3.1.json', host: 'https://petstore.swagger.io', basePath: '/v1' },
+ { version: '3.2', seed: '../seeds/parserInitialGoodOpenApi3.2.json', host: 'https://petstore.swagger.io', basePath: '/v1' },
+];
describe('parser-schemaHostBasePath', () => {
it('good swagger2', () => {
-
globalThis.definition = require('../seeds/parserSchemaHostBasePathInitialGood.json');
-
const schemaHostBasePath = require('../src/parser/swagger2/schemaHostBasePath.js')();
assert.deepStrictEqual(schemaHostBasePath, { host: 'https://myserver.com', basePath: '/first/second' });
- })
-
- it('good openapi3.0', () => {
-
- globalThis.definition = require('../seeds/parserInitialGoodOpenApi3.json');
-
- const schemaHostBasePath = require('../src/parser/openapi3/schemaHostBasePath.js')();
- assert.deepStrictEqual(schemaHostBasePath, { host: 'http://petstore.swagger.io', basePath: '/v1' });
- })
-
- it('good openapi3.1', () => {
-
- globalThis.definition = require('../seeds/parserInitialGoodOpenApi3.1.json');
-
- const schemaHostBasePath = require('../src/parser/openapi3/schemaHostBasePath.js')();
- assert.deepStrictEqual(schemaHostBasePath, { host: 'https://petstore.swagger.io', basePath: '/v1' });
- })
+ });
+
+ openapi3Cases.forEach(({ version, seed, host, basePath }) => {
+ it(`good openapi${version}`, () => {
+ globalThis.definition = require(seed);
+ const schemaHostBasePath = require('../src/parser/openapi3/schemaHostBasePath.js')();
+ assert.deepStrictEqual(schemaHostBasePath, { host, basePath });
+ });
+ });
});
\ No newline at end of file
diff --git a/test/parser-status.js b/test/parser-status.js
index 28b7009..ff2e11e 100644
--- a/test/parser-status.js
+++ b/test/parser-status.js
@@ -1,6 +1,6 @@
/** Part of APIAddicts. See LICENSE fileor full copyright and licensing details. Supported by Madrid Digital and CloudAPPi **/
-const assert = require('assert');
+const assert = require('node:assert');
describe('parser-status', () => {
@@ -28,4 +28,12 @@ describe('parser-status', () => {
assert.deepStrictEqual(status, [ 201, 500 ])
})
+ it('good openapi3.2', () => {
+
+ globalThis.definition = require('../seeds/parserInitialGoodOpenApi3.2.json')
+
+ const status = require('../src/parser/status.js')('POST','/pets')
+ assert.deepStrictEqual(status, [ 201, 500 ])
+ })
+
});
\ No newline at end of file
diff --git a/test/parser-summary.js b/test/parser-summary.js
index 4f6a74f..e3495af 100644
--- a/test/parser-summary.js
+++ b/test/parser-summary.js
@@ -1,6 +1,6 @@
/** Part of APIAddicts. See LICENSE fileor full copyright and licensing details. Supported by Madrid Digital and CloudAPPi **/
-const assert = require('assert');
+const assert = require('node:assert');
describe('parser-summary', () => {
@@ -28,4 +28,12 @@ describe('parser-summary', () => {
assert.equal(summary, "Create pet")
})
+ it('good openapi3.2', () => {
+
+ globalThis.definition = require('../seeds/parserSummaryOpenApi3.2.json')
+
+ const summary = require('../src/parser/summary.js')('POST','/pets')
+ assert.equal(summary, "Create pet")
+ })
+
})
\ No newline at end of file
diff --git a/test/parser-version.js b/test/parser-version.js
index b466e06..85d050b 100644
--- a/test/parser-version.js
+++ b/test/parser-version.js
@@ -1,62 +1,31 @@
/** Part of APIAddicts. See LICENSE fileor full copyright and licensing details. Supported by Madrid Digital and CloudAPPi **/
-const assert = require('assert')
+const assert = require('node:assert')
+
+const openapi3Cases = [
+ { name: 'openapi3.0', seed: '../seeds/parserInitialGoodOpenApi3.json' },
+ { name: 'openapi version 3.0.2', seed: '../seeds/parserInitialGoodOpenApi3.0.2.json' },
+ { name: 'openapi version 3.0.3', seed: '../seeds/parserInitialGoodOpenApi3.0.3.json' },
+ { name: 'openapi3.1', seed: '../seeds/parserInitialGoodOpenApi3.1.json' },
+ { name: 'openapi version 3.1.1', seed: '../seeds/parserInitialGoodOpenApi3.1.1.json' },
+ { name: 'openapi version 3.1.2', seed: '../seeds/parserInitialGoodOpenApi3.1.2.json' },
+ { name: 'openapi3.2', seed: '../seeds/parserInitialGoodOpenApi3.2.json' },
+ { name: 'openapi version 3.2.0', seed: '../seeds/parserInitialGoodOpenApi3.2.0.json' },
+];
describe('parser-version', () => {
-
- it('swagger2', () => {
-
- globalThis.definition = require('../seeds/parserInitialGood.json')
- const version = require('../src/parser/version.js')()
- assert.equal(version, 'swagger2')
+ it('swagger2', () => {
+ globalThis.definition = require('../seeds/parserInitialGood.json');
+ const version = require('../src/parser/version.js')();
+ assert.equal(version, 'swagger2');
});
- it('openapi3.0', () => {
-
- globalThis.definition = require('../seeds/parserInitialGoodOpenApi3.json')
-
- const version = require('../src/parser/version.js')()
- assert.equal(version, 'openapi3')
+ openapi3Cases.forEach(({ name, seed }) => {
+ it(name, () => {
+ globalThis.definition = require(seed);
+ const version = require('../src/parser/version.js')();
+ assert.equal(version, 'openapi3');
+ });
});
-
- it('openapi version 3.0.2' , () => {
-
- globalThis.definition = require('../seeds/parserInitialGoodOpenApi3.0.2.json')
-
- const version = require('../src/parser/version.js')()
- assert.equal(version, 'openapi3')
- })
-
- it('openapi version 3.0.3' , () => {
-
- globalThis.definition = require('../seeds/parserInitialGoodOpenApi3.0.3.json')
-
- const version = require('../src/parser/version.js')()
- assert.equal(version, 'openapi3')
- })
-
- it('openapi3.1', () => {
-
- globalThis.definition = require('../seeds/parserInitialGoodOpenApi3.1.json')
-
- const version = require('../src/parser/version.js')()
- assert.equal(version, 'openapi3')
- });
-
- it('openapi version 3.1.1' , () => {
-
- globalThis.definition = require('../seeds/parserInitialGoodOpenApi3.1.1.json')
-
- const version = require('../src/parser/version.js')()
- assert.equal(version, 'openapi3')
- })
-
- it('openapi version 3.1.2' , () => {
-
- globalThis.definition = require('../seeds/parserInitialGoodOpenApi3.1.2.json')
-
- const version = require('../src/parser/version.js')()
- assert.equal(version, 'openapi3')
- })
});
\ No newline at end of file