I am new to jq and this one seems impossible to write. So need some help from jq gurus out there:
So I have an Open API spec file, let's take version 3.0 for example:
The paths
element has endpoints
listed, and each of them has methods(get
, post
, etc.)
I need a jq filter to select ONLY those methods marked with "x-visibility": "public"
and leave everything else out.
So far, I've tried this:
.paths |= map(select(.[]."x-visibility" == "public" | not))
Obviously, it doesn't work.
Any help/pointers will be appreciated!
Here is the OpenAPI 3.0 spec file (extra stuff stripped off):
{
"openapi": "3.0.1",
"info": {
"title": "API service",
"description": "Exposing useful methods",
"x-descriptionForPublicDocs": "This is a test description for public docs specifically",
"contact": {
"name": "Message me",
"url": "https://message.me"
},
"version": "1.0"
},
"servers": [
{
"url": "http://localhost:9090",
"description": "Generated server url"
}
],
"tags": [
{
"name": "AccountGroups"
}
],
"x-tags": [
{
"name": "TestResourceLists"
}
],
"paths": {
"/crane/v1/resource_list/{id}": {
"get": {
"tags": [
"ResourceLists"
],
"x-tags": "TestResourceLists",
"x-visibility": "public",
"summary": "Get Resource List by ID",
"description": "Returns the resource list that has the specified ID.",
"operationId": "getById",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ResourceList Id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Successful operation",
"content": {
"application/json; charset=UTF-8": {
"schema": {
"$ref": "#/components/schemas/ResourceListModel"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"4XX": {
"description": "Client error",
"content": {
"application/json; charset=UTF-8": {
"schema": {
"$ref": "#/components/schemas/SpringErrorResponse"
}
}
}
}
}
},
"put": {
"tags": [
"ResourceLists"
],
"x-visibility": "internal",
"summary": "Update Resource List",
"description": "Updates the resource list that has the specified ID.",
"operationId": "update",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ResourceList Id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"description": "Model for Resource List",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResourceListModel"
},
"examples": {
"TAG": {
"description": "Tag ResourceList",
"value": {
"members": [
{
"string": "string"
}
],
"name": "string",
"resourceListType": "TAG",
"description": "string"
}
},
"RESOURCE_GROUP": {
"description": "RESOURCE_GROUP ResourceList",
"value": {
"description": "string",
"members": [
"string",
"string"
],
"name": "string",
"resourceListType": "RESOURCE_GROUP"
}
},
"COMPUTE_ACCESS_GROUP": {
"description": "COMPUTE_ACCESS_GROUP ResourceList",
"value": {
"description": "string",
"members": [
{
"appIDs": [
"*"
],
"clusters": [
"*"
],
"codeRepos": [
"*"
],
"containers": [
"*"
],
"functions": [
"*"
],
"hosts": [
"*"
],
"images": [
"*"
],
"labels": [
"*"
],
"namespaces": [
"*"
]
}
],
"name": "string",
"resourceListType": "COMPUTE_ACCESS_GROUP"
}
}
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Successful operation",
"content": {
"application/json; charset=UTF-8": {
"schema": {
"$ref": "#/components/schemas/ResourceListModel"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"4XX": {
"description": "Client error",
"content": {
"application/json; charset=UTF-8": {
"schema": {
"$ref": "#/components/schemas/SpringErrorResponse"
}
}
}
}
}
},
"delete": {
"tags": [
"ResourceLists"
],
"x-visibility": "internal",
"summary": "Delete Resource List",
"description": "Deletes the resource list that has the specified ID.",
"operationId": "delete",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ResourceList Id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "Successful operation"
},
"400": {
"description": "Bad Request",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"4XX": {
"description": "Client error",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/SpringErrorResponse"
}
}
}
}
}
}
},
"/crane/v1/account_group/{id}": {
"get": {
"tags": [
"AccountGroups"
],
"x-visibility": "public",
"summary": "Get resource",
"description": "Returns something",
"operationId": "getById_1",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Account Group ID",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "includeAccountInfo",
"in": "query",
"description": "Include Cloud Account details",
"required": false,
"schema": {
"type": "boolean"
}
}
],
"responses": {
"200": {
"description": "Successful operation",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AccountGroupModel"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"4XX": {
"description": "Client error",
"content": {
"application/json; charset=UTF-8": {
"schema": {
"$ref": "#/components/schemas/SpringErrorResponse"
}
}
}
}
},
},
"put": {
"tags": [
"AccountGroups"
],
"x-visibility": "internal",
"summary": "Update resource",
"description": "Update information",
"operationId": "update_1",
"parameters": [
{
"name": "id",
"in": "path",
"description": "AccountGroup Id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json; charset=UTF-8": {
"schema": {
"$ref": "#/components/schemas/AccountGroupModel"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Successful operation"
},
"400": {
"description": "Bad Request",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"4XX": {
"description": "Client error",
"content": {
"application/json; charset=UTF-8": {
"schema": {
"$ref": "#/components/schemas/SpringErrorResponse"
}
}
}
}
}
},
"delete": {
"tags": [
"AccountGroups"
],
"x-visibility": "internal",
"summary": "Delete resource",
"description": "Deletes the resource",
"operationId": "delete_1",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Delete resource",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Successful operation"
},
"400": {
"description": "Bad Request",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
},
"4XX": {
"description": "Client error",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/SpringErrorResponse"
}
}
}
}
}
}
}
}
}
CodePudding user response:
.paths |= map_values(
if type == "object"
then with_entries(select(
if .value|objects|has("x-visibility")
then .value|.["x-visibility"] == "public"
else true end) )
else . end)
CodePudding user response:
Use map_values
to apply a function to all values of an object. You have two nested objects, so you need to call map_values
twice:
.paths |= map_values(map_values(select(."x-visibility" == "public")))
To strip empty paths, select only those values which are not an empty array:
.paths |= map_values(
map_values(select(."x-visibility" == "public"))
| select(. != {})
)
or perhaps even one of the following:
.paths |= map_values(
map_values(select(."x-visibility" == "public"))
| select(length > 0)
)
.paths |= map_values(
map_values(select(."x-visibility" == "public"))
| select(any)
)