orval
orval copied to clipboard
OpenAPI spec parsing bug
What are the steps to reproduce this issue?
- Run Orval using an OpenAPI spec containing the following (sanitised) section. Only provide the input and output parameters on CLI.
{
"openapi": "3.0.1",
"info": {
"title": "API",
"description": "An API",
"termsOfService": "https://example.com",
"license": {
"name": "company",
"url": "https://www.example.com"
},
"version": "1.0.0"
},
"servers": [
{
"url": "https://dev.dev",
"description": "Generated server url"
}
],
"paths": {
"/api/v1/path/{additional}" : {
"get": {
"tags": [],
"summary": "Fetches",
"operationId": "getHierarchy_1",
"parameters": [
{
"name": "hierarchy",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "requestParameters",
"in": "query",
"required": true,
"schema": {
"$ref": "#/components/schemas/HierarchyRequestParams"
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ResponseWrapperHierarchyBean"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ResponseWrapperHierarchyBean"
}
}
}
}
}
}
},
"/api/v1/path1/{otherAdditional}" : {
"get": {
"tags": [],
"summary": "Fetches",
"operationId": "getHierarchy_2",
"parameters": [
{
"name": "requestParameters",
"in": "query",
"required": true,
"schema": {
"$ref": "#/components/schemas/HierarchyRequestParams"
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ResponseWrapperHierarchyBean"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ResponseWrapperHierarchyBean"
}
}
}
}
},
"deprecated": true
}
}
}
}
What happens?
Orval fails to complete the generation process.
What were you expecting to happen?
Orval should have completed the generation process successfully.
Any logs, error output, etc?
api - Error: The path params level can't be found in parameters (getHierarchy_2)
at /users/dev/app/node_modules/@orval/core/dist/index.js:49180:13
at Array.map (<anonymous>)
at getParams (/users/dev/app/node_modules/@orval/core/dist/index.js:49171:17)
at generateVerbOptions (/users/dev/app/node_modules/@orval/core/dist/index.js:50418:18)
at /users/dev/app/node_modules/@orval/core/dist/index.js:50502:33
at asyncReduce (/users/dev/app/node_modules/@orval/core/dist/index.js:47318:24)
at generateVerbsOptions (/users/dev/app/node_modules/@orval/core/dist/index.js:50498:7)
at api.operations (/users/dev/app/node_modules/orval/dist/bin/orval.js:3429:70)
at asyncReduce (/users/dev/app/node_modules/@orval/core/dist/index.js:47318:24)
at async getApiBuilder (/users/dev/app/node_modules/orval/dist/bin/orval.js:3413:15)
Any other comments?
I had a conversation about this on the Orval DIscord on August 23 2024 (username: helveticDev).
The OpenAPI spec validates and works without issues with npx openapi-typescript.
What versions are you using?
System:
OS: macOS 14.6.1
CPU: (8) arm64 Apple M2
Memory: 44.64 MB / 16.00 GB
Shell: 5.9 - /bin/zsh
npmPackages:
msw: ^2.3.1 => 2.3.1
orval: ^7.0.1 => 7.0.1
react: ^18.3.1 => 18.3.1
@sengeezer i see its referencing params like "$ref": "#/components/schemas/HierarchyRequestParams" but I don't see those in your Schema. Could that be the issue its trying to reference something that doesn't exist?
Also I see this /api/v1/path1/{otherAdditional} so its expecting a path param called OtherAdditional but i don't see that listed in your OpenAPI either.
For example here is one of mine.
"/administrator/queue/{id}" : {
"get" : {
"tags" : [ "Mobile Synchronization Administrator Resource" ],
"parameters" : [ {
"name" : "id",
"in" : "path",
"required" : true,
"schema" : {
"format" : "int64",
"minimum" : 0,
"type" : "integer"
}
} ],
"responses" : {
"200" : {
"description" : "OK",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/IosNotificationQueue"
}
}
}
}
}
}
},
see how the path param id has a matching declaration.
Ok, I can see I've sanitised the spec into invqalidity. I have asked for permission to share more.
I also just verified that your competitor (?) openapi-ts also has no issues parsing the same OpenAPI spec. Hopefully I will recieve approval so Orval is not the only one to barf on the spec. :)
looks like openapi-ts doesn't do TanStack Query? only native Fetch?
Ok, my infosec analyst has approved the following. Will this help?
{
"openapi": "3.0.1",
"info": {
"title": "API",
"description": "An API",
"termsOfService": "https://example.com",
"license": {
"name": "company",
"url": "https://www.example.com"
},
"version": "1.0.0"
},
"servers": [
{
"url": "https://dev.dev",
"description": "Generated server url"
}
],
"paths": {
"/api/v1/path/{hierarchy}": {
"get": {
"tags": [],
"summary": "Fetches",
"operationId": "getHierarchy_1",
"parameters": [
{
"name": "hierarchy",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "requestParameters",
"in": "query",
"required": true,
"schema": {
"$ref": "#/components/schemas/HierarchyRequestParams"
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ResponseWrapperHierarchyBean"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ResponseWrapperHierarchyBean"
}
}
}
}
}
}
},
"/api/v1/path1/{level}": {
"get": {
"tags": [],
"summary": "Fetches",
"operationId": "getHierarchy_2",
"parameters": [
{
"name": "requestParameters",
"in": "query",
"required": true,
"schema": {
"$ref": "#/components/schemas/HierarchyRequestParams"
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ResponseWrapperHierarchyBean"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/ResponseWrapperHierarchyBean"
}
}
}
}
},
"deprecated": true
}
}
},
"components": {
"schemas": {
"HierarchyRequestParams": {
"type": "object",
"properties": {
"query": {
"type": "string"
},
"search": {
"type": "string"
},
"searchType": {
"type": "string",
"enum": [
"INCREMENTAL",
"COMPLETE",
"ALL_LEVELS",
"ALL_SKUS"
]
},
"licenced": {
"type": "boolean"
},
"value": {
"type": "integer",
"format": "int64"
},
"level": {
"type": "string"
},
"useFilter": {
"type": "boolean"
},
"sortBy": {
"type": "string"
},
"tradingHierarchy": {
"type": "array",
"items": {
"type": "string"
}
},
"brand": {
"type": "array",
"items": {
"type": "string"
}
},
"ownBrand": {
"type": "array",
"items": {
"type": "string"
}
},
"manufacturer": {
"type": "array",
"items": {
"type": "string"
}
},
"packSize": {
"type": "array",
"items": {
"type": "string"
}
},
"unitOfMeasure": {
"type": "array",
"items": {
"type": "string"
}
},
"measures": {
"type": "array",
"items": {
"type": "string"
}
},
"resolve": {
"type": "string",
"enum": [
"category",
"product",
"brand",
"own_brand",
"all"
]
},
"ownBrandOnly": {
"type": "boolean"
},
"liveSkusOnly": {
"type": "boolean"
},
"minMeasure": {
"type": "integer",
"format": "int32"
},
"maxMeasure": {
"type": "integer",
"format": "int32"
},
"atomicMeasures": {
"type": "array",
"items": {
"type": "integer",
"format": "int32"
}
},
"brandIds": {
"type": "array",
"items": {
"type": "integer",
"format": "int64"
}
},
"ownBrandLabels": {
"type": "array",
"items": {
"type": "string"
}
},
"splitSearchTerms": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"ResponseWrapperHierarchyBean": {
"type": "object",
"properties": {
"timestamp": {
"type": "string",
"format": "date-time"
},
"status": {
"type": "string",
"enum": [
"100 CONTINUE",
"101 SWITCHING_PROTOCOLS",
"102 PROCESSING",
"103 EARLY_HINTS",
"103 CHECKPOINT",
"200 OK",
"201 CREATED",
"202 ACCEPTED",
"203 NON_AUTHORITATIVE_INFORMATION",
"204 NO_CONTENT",
"205 RESET_CONTENT",
"206 PARTIAL_CONTENT",
"207 MULTI_STATUS",
"208 ALREADY_REPORTED",
"226 IM_USED",
"300 MULTIPLE_CHOICES",
"301 MOVED_PERMANENTLY",
"302 FOUND",
"302 MOVED_TEMPORARILY",
"303 SEE_OTHER",
"304 NOT_MODIFIED",
"305 USE_PROXY",
"307 TEMPORARY_REDIRECT",
"308 PERMANENT_REDIRECT",
"400 BAD_REQUEST",
"401 UNAUTHORIZED",
"402 PAYMENT_REQUIRED",
"403 FORBIDDEN",
"404 NOT_FOUND",
"405 METHOD_NOT_ALLOWED",
"406 NOT_ACCEPTABLE",
"407 PROXY_AUTHENTICATION_REQUIRED",
"408 REQUEST_TIMEOUT",
"409 CONFLICT",
"410 GONE",
"411 LENGTH_REQUIRED",
"412 PRECONDITION_FAILED",
"413 PAYLOAD_TOO_LARGE",
"413 REQUEST_ENTITY_TOO_LARGE",
"414 URI_TOO_LONG",
"414 REQUEST_URI_TOO_LONG",
"415 UNSUPPORTED_MEDIA_TYPE",
"416 REQUESTED_RANGE_NOT_SATISFIABLE",
"417 EXPECTATION_FAILED",
"418 I_AM_A_TEAPOT",
"419 INSUFFICIENT_SPACE_ON_RESOURCE",
"420 METHOD_FAILURE",
"421 DESTINATION_LOCKED",
"422 UNPROCESSABLE_ENTITY",
"423 LOCKED",
"424 FAILED_DEPENDENCY",
"425 TOO_EARLY",
"426 UPGRADE_REQUIRED",
"428 PRECONDITION_REQUIRED",
"429 TOO_MANY_REQUESTS",
"431 REQUEST_HEADER_FIELDS_TOO_LARGE",
"451 UNAVAILABLE_FOR_LEGAL_REASONS",
"500 INTERNAL_SERVER_ERROR",
"501 NOT_IMPLEMENTED",
"502 BAD_GATEWAY",
"503 SERVICE_UNAVAILABLE",
"504 GATEWAY_TIMEOUT",
"505 HTTP_VERSION_NOT_SUPPORTED",
"506 VARIANT_ALSO_NEGOTIATES",
"507 INSUFFICIENT_STORAGE",
"508 LOOP_DETECTED",
"509 BANDWIDTH_LIMIT_EXCEEDED",
"510 NOT_EXTENDED",
"511 NETWORK_AUTHENTICATION_REQUIRED"
]
},
"errors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ValidationErrorMappingBean"
}
},
"body": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ProductHierarchyBean"
}
}
}
},
"ValidationErrorMappingBean": {
"type": "object",
"properties": {
"fieldMappings": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"writeOnly": true
}
}
},
"ProductHierarchyBean": {
"type": "object",
"properties": {
"value": {
"type": "integer",
"format": "int64"
},
"label": {
"type": "string"
},
"level": {
"type": "string"
},
"accesslevels": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AccessLevelsBean"
}
},
"children": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ProductHierarchyBean"
}
},
"skuCount": {
"type": "integer",
"format": "int32"
},
"isFinal": {
"type": "boolean"
},
"isProductLevel": {
"type": "boolean"
},
"fullAccess": {
"type": "boolean"
},
"parent": {
"$ref": "#/components/schemas/ProductHierarchyBean"
},
"groupLabel": {
"type": "string"
},
"id": {
"type": "string"
},
"searchIndex": {
"type": "string"
},
"parents": {
"type": "string"
}
}
},
"AccessLevelsBean": {
"type": "object",
"properties": {
"epos": {
"type": "string"
},
"access": {
"type": "string"
}
}
}
}
}
}
if you run the above through the CLI does it error the same way?
It does, yes.
The new stack trace:
api - Error: The path params level can't be found in parameters (getHierarchy_2)
at /users/dev/app/node_modules/@orval/core/dist/index.js:49180:13
at Array.map (<anonymous>)
at getParams (/users/dev/app/node_modules/@orval/core/dist/index.js:49171:17)
at generateVerbOptions (/users/dev/app/node_modules/@orval/core/dist/index.js:50418:18)
at /users/dev/app/node_modules/@orval/core/dist/index.js:50502:33
at asyncReduce (/users/dev/app/node_modules/@orval/core/dist/index.js:47318:24)
at generateVerbsOptions (/users/dev/app/node_modules/@orval/core/dist/index.js:50498:7)
at api.operations (/users/dev/app/node_modules/orval/dist/bin/orval.js:3429:70)
at asyncReduce (/users/dev/app/node_modules/@orval/core/dist/index.js:47318:24)
at async getApiBuilder (/users/dev/app/node_modules/orval/dist/bin/orval.js:3413:15)
@anymaniax / @melloware : Are there any updates on this? Could you give me an ETA for this to be fixed?
I can confirm that v7.1.0 does NOT fix this bug.
No ETA from my end i would expect someone in the community needs to submit a PR to fix this issue.
This crash because the path /api/v1/path1/{level} has a param level and it's not described in the parameters array. It's the good behavior or I miss something?