yq add property to object somewhere in the tree - yaml

I'm trying to add a response to all objects with the key responses in an open api yaml file. I tried a lot and failed hard because I think I miss some basic understanding but I don't know what exactly.
File
openapi: 3.0.1
info:
title: my service
description: API for my service
version: 1.0.0
security:
- jwt:
- read
paths:
'/foo/{fooId}/firmware/update-request':
post:
parameters:
- name: fooId
in: path
description: Foo Id
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/FooRequest'
example:
firmwareVersion: "0.1"
responses:
'202':
description: Foo has been done
'400':
$ref: '#/components/responses/BadRequest'
'409':
$ref: '#/components/responses/Conflict'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/ServerError'
'502':
$ref: '#/components/responses/BadGateway'
'/foo/{fooId}/firmware/auto-update':
put:
parameters:
- name: fooId
in: path
description: Foo Id
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/FooUpdate'
example:
enabled: true
responses:
'204':
description: Foo update
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/ServerError'
'502':
$ref: '#/components/responses/BadGateway'
# goes on forever
Goal is that every response looks like
responses:
'204':
description: Foo update
# ...
'xxx':
description: yyy
while keeping the file structure intact.
What I tried:
yq -i '.. | select(has("responses")).responses | . += {"xxx": {"description": yyy}}' my.yaml
This was the idea, that came the closet my my expected result. But now every node from root to responses are missing.
What is the correct syntax to tell yq "Do this transformation in place on every node with this name without knowing it's level and without affecting every other node"?

You were almost there. Just wrap the whole search on the LHS into parentheses to eventually retain the outer context:
(.. | select(has("responses")).responses) += {"xxx": {"description": "yyy"}}
Note: I have also wrapped yyy in quotes and simplified | . += to just +=.
You could also just set the xxx field directly:
(.. | select(has("responses")).responses).xxx = {"description": "yyy"}
Both of these assume to be executed with mikefarah/yq. For a kislyuk/yq solution, add a ? to get has("responses")? as .. will also capture non-objects.
This was tested on mikefarah/yq version 4.20.2, and on kislyuk/yq version 3.0.2.

Related

Redocly OpenAPI structure error. Property `openapi` is not expected here

I am trying to create an api documentation using redocly.
On my openapi.yaml it is linking to a yaml that has the api docs called kpi-documentation.yaml
link/$ref in openapi.yaml
/kpiDocumentation:
$ref: paths/kpi-documentation.yaml
I have an error in my visual studio code redocly preview extension that says
We found structural problems in your definition, please check the files below before running the preview.
File: /Users/xx/Desktop/Projects/api-docs/openapi/paths/kpi-documentation.yaml
Problem: Property `openapi` is not expected here.
File: /Users/xx/Desktop/Projects/api-docs/openapi/paths/kpi-documentation.yaml
Problem: Property `info` is not expected here.
File: /Users/xx/Desktop/Projects/api-docs/openapi/paths/kpi-documentation.yaml
Problem: Property `paths` is not expected here.
File: /Users/xx/Desktop/Projects/api-docs/openapi/paths/kpi-documentation.yaml
Problem: Property `components` is not expected here.
Part of code that I have in the kpi-documentation.yaml that appears to be throwing the error is
openapi: "3.1"
info:
title: KPI API
version: '1.0'
description: Documentation of API endpoints of KPI
servers:
- url: https://api.redocly.com
paths:
I have checked the documentation on the redocly website and it looks like my yaml structure is fine.
Also to note the kpi-documentation previews fine by itself when using the preview, but not when I preview the openapi.yaml which is the root file that needs to work.
https://redocly.com/docs/openapi-visual-reference/openapi/#OAS-3.0
rootfile
openapi.yaml
openapi: 3.1.0
info:
version: 1.0.0
title: KPI API documentation
termsOfService: 'https://example.com/terms/'
contact:
name: Brendan
url: 'http://example.com/contact'
license:
name: Apache 2.0
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
x-logo:
url: 'https://www.feedgy.solar/wp-content/uploads/2022/07/Sans-titre-1.png'
tags:
- name: Insert Service 1
description: Example echo operations.
- name: Insert Service 2
description: Operations about users.
- name: Insert Service 3
description: This is a tag description.
- name: Insert Service 4
description: This is a tag description.
servers:
- url: 'https://{tenant}/api/v1'
variables:
tenant:
default: www
description: Your tenant id
- url: 'https://example.com/api/v1'
paths:
'/users/{username}':
$ref: 'paths/users_{username}.yaml'
/echo:
$ref: paths/echo.yaml
/pathItem:
$ref: paths/path-item.yaml
/pathItemWithExamples:
$ref: paths/path-item-with-examples.yaml
/kpiDocumentation:
$ref: 'paths/kpi-documentation.yaml'
pathitem file
kpi-documentation.yaml
openapi: "3.1"
info:
title: KPI API
version: '1.0'
description: Documentation of API endpoints of KPI
servers:
- url: https://api.redocly.com
paths:
"/api/v1/corrected-performance-ratio/plants/{id}":
get:
summary: Same as the Performance Ratio, but the ratio is done using Corrected Reference Yield, so it considers thermal losses in the panels as normal. The WCPR represents the losses in the BoS (balance of system), so everything from the panel DC output to the AC output.
operationId: corrected_performance_ratio_plants_retrieve
parameters:
- in: query
name: date_end
schema:
type: string
format: date
required: true
- in: query
name: date_start
schema:
type: string
format: date
required: true
- in: query
name: frequency
schema:
enum:
- H
- D
- M
- Y
type: string
default: H
minLength: 1
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this plant.
required: true
- in: query
name: threshold
schema:
type: integer
default: 50
tags:
- corrected-performance-ratio
security:
- tokenAuth: []
- cookieAuth: []
- {}
responses:
"200":
content:
application/json:
schema:
$ref: "#/components/schemas/KPIResponse"
description: ""
"/api/v1/corrected-performance-ratio/plants/{id}/inverters":

Remove a specific parameter and examples from Swagger Doc

I have a swagger.yaml file having a lot of APIs. I would like to remove all the parameters with the name of user-id from all of the APIs. Also, there are examples and x-examples which are irrelevant for my use-case that I would like to be removed.
I have been experimenting with openapi-filter. However, for it to work I'll have to add a special tag to the parameters and it won't work for examples. I could also be using it incorrectly.
parameters:
- name: action-id
in: path
description: Action ID which needs to be failed
required: true
type: integer
format: int64
x-example: 1
- name: action-category-number
in: path
description: Action category number which needs to be failed
required: true
type: integer
format: int64
example: 2
- name: user-id
in: header
description: User under which the action exists
required: true
type: integer
format: int32
x-example: 1
Expected output:
parameters:
- name: action-id
in: path
description: Action ID which needs to be failed
required: true
type: integer
format: int64
- name: action-category-number
in: path
description: Action category number which needs to be failed
required: true
type: integer
format: int64

Swagger.io / OpenAPI - How to reuse complete code blocks

I have status codes from the server that keep repeating in the documentation:
responses:
'204':
$ref: '#/components/responses/204'
'400':
$ref: '#/components/responses/400'
'401':
$ref: '#/components/responses/401'
'402':
$ref: '#/components/responses/402'
'403':
$ref: '#/components/responses/403'
'404':
$ref: '#/components/responses/404'
'426':
$ref: '#/components/responses/426'
'429':
$ref: '#/components/responses/429'
How can I use Swagger.io's OpenAPI to lay a reference so that I only have one short line at a time, example:
responses:
$ref: '#/components/responses/defaultCodes'
And is it also possible to expand the list with "allOf"?
responses:
allOf:
- '200':
$ref: '#/components/responses/200'
- $ref: '#/components/responses/defaultCodes'
Thank you very much for your help : )
This is not supported.
Here are the related feature requests in the OpenAPI Specification repository:
Add default responses
Traits or Mixins
Group multiple parameter definitions for better maintainability (even though it's about parameters, a generic solution could extend to responses)

How to use $ref for tags between files

I am using Open API 3.0, in A.yaml
# something above
tags:
- name: user
description: Operations about user
- name: user_stuff
description: API for user stuff
- name: another_user_stuff
description: API for another user stuff
# something below
Then, in B.yaml, I want to make reference to the tags in A.yaml, for example the tag of user. Suppose in B.yaml, we have
post:
tags:
$ref: <What are the things should be here?>
summary: do somthing
description: "do something"
requestBody:
# bla bla bla
required: true
responses:
"200":
description: uccessfully
x-swagger-router-controller: B
How can I make a reference from B.yaml to A.yaml?
The tags keyword does not support $ref. All tags must be defined inline.
# B.yaml
tags:
- name: foo
description: Operations to manage Foos.
paths:
/something:
post:
tags:
- foo
- bar
That said, you don't have to define tags in the global tags section in order to use them in operations. The global tags section is used only to define extra tag metadata, such as descriptions and externalDocs, or the tag order in documentation tools.

Create complex types (definitions) in Swagger [duplicate]

This question already has answers here:
Swagger: How to have a property reference a model in OpenAPI 2.0 (i.e. nest the models)?
(2 answers)
Closed 2 years ago.
I created a definition called Product and another called Text (see code).
On parameters of paths I can not use the type Text created in definitions. On the definition Product I have a property called message and I want that property to be the type Text too.
(...)
paths:
/products:
get:
summary: Product Types
description: |
Description text
parameters:
- name: latitude
in: query
description: Latitude component of location.
required: true
### The type Text was not found here
type: Text ### The type Text was not found here
(...)
definitions:
Product:
properties:
message:
### The type Text was not found here
type: Text ### Compilation Error in this line ####
name:
type: string
description: Data description.
Text:
properties:
code:
type: string
But this error occurs:
Swagger Error:
Data does not match any schemas from 'anyOf'.
How can I reference the type Text on the type Product?
Please use $ref instead. Here is an example
type: object
required:
- name
properties:
name:
type: string
address:
$ref: '#/definitions/Address'
age:
type: integer
format: int32
minimum: 0
Ref: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#simple-model

Resources