使用 jq 进行转换时如何引用 'subdocument'

How to refer to 'subdocument' in when doing transformations with jq

我正在尝试使用 jq 转换 OpenAPI 规范文件。我想要 'recognise' 模式

"status": {
  "allOf": [
    {
      "$ref": "#/components/schemas/Status"
    },
    {
      "description": "Status"
    }
  ]
}

并将其更改为

"status": {
  "$ref": "#/components/schemas/Status"
}

我认为这并不难,但是当我尝试在更大的示例上执行此操作时,我 运行 遇到了麻烦。让我们举个例子:

  {
    "components": {
      "schemas": {
        "ObjectStatusType": {
          "required": [
            "status",
            "type",
            "agreement"
          ],
          "type": "object",
          "properties": {
            "agreement": {
              "description": "An agreement",
              "maxLength": 5,
              "type": "string"
            },
            "status": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/Status"
                },
                {
                  "description": "Status"
                }
              ]
            },
            "type": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/Type"
                },
                {
                  "description": "Type"
                }
              ]
            }
          }
        },
        "BallType": {
          "required": [
            "colour",
            "type",
            "physics"
          ],
          "type": "object",
          "properties": {
            "colour": {
              "description": "Ball colour",
              "maxLength": 5,
              "type": "string"
            },
            "type": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/Type"
                },
                {
                  "description": "Type"
                }
              ]
            },
            "physics": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/Physics"
                },
                {
                  "description": "Physics"
                }
              ]
            }
          }
        }
      }
    }
  }

我想变成

  {
    "components": {
      "schemas": {
        "ObjectStatusType": {
          "required": [
            "status",
            "type",
            "agreement"
          ],
          "type": "object",
          "properties": {
            "agreement": {
              "description": "An agreement",
              "maxLength": 5,
              "type": "string"
            },
            "status": {
              "$ref": "#/components/schemas/Status"
            },
            "type": {
              "$ref": "#/components/schemas/Type"
            }
          }
        },
        "BallType": {
          "required": [
            "colour",
            "type",
            "physics"
          ],
          "type": "object",
          "properties": {
            "colour": {
              "description": "Ball colour",
              "maxLength": 5,
              "type": "string"
            },
            "type": {
              "$ref": "#/components/schemas/Type"
            },
            "physics": {
              "$ref": "#/components/schemas/Physics"
            }
          }
        }
      }
    }
  }

我已经尝试使用表达式 (.components | .schemas | .[] | .properties // empty | .[] | select(.allOf // empty | .[] // empty | .description) | select(.allOf // empty | .[] // empty | ."$ref")) = { "$ref" : "what to put here" } ,它给了我

{
  "components": {
    "schemas": {
      "ObjectStatusType": {
        "required": [
          "status",
          "type",
          "agreement"
        ],
        "type": "object",
        "properties": {
          "agreement": {
            "description": "An agreement",
            "maxLength": 5,
            "type": "string"
          },
          "status": {
            "$ref": "what to put here"
          },
          "type": {
            "$ref": "what to put here"
          }
        }
      },
      "BallType": {
        "required": [
          "colour",
          "type",
          "physics"
        ],
        "type": "object",
        "properties": {
          "colour": {
            "description": "Ball colour",
            "maxLength": 5,
            "type": "string"
          },
          "type": {
            "$ref": "what to put here"
          },
          "physics": {
            "$ref": "what to put here"
          }
        }
      }
    }
  }
}

我需要一些参考 'subdocument' 而不是 what to put here。我试过变量,但只能全局定义,右边的.指的是整个文档,而不仅仅是被替换的部分。

我们将 YAML 用于 OpenAPI 规范,因此,如果有一个解决方案也适用于 yq,那将是更可取的。

鉴于显示的输入,以下 jq 程序产生了预期的输出并且似乎符合一般要求,并且应该很容易根据您更详细的要求进行修改:

walk(if type=="object" and (.allOf | (type == "array") and (length == 2))
     then {"$ref": .allOf[0]["$ref"]}
     else . end)

FYPI,“then”子句可以缩写为:

.allOf[0] | {"$ref"}