JSONPath-Plus / JSONPath

A fork of JSONPath from http://goessner.net/articles/JsonPath/
Other
963 stars 169 forks source link

Add regex matching support in filters (similar to JayWay pattern support) #122

Closed vitaly-magyari closed 4 years ago

vitaly-magyari commented 4 years ago

So I have my openAPI 3.0.0 fragment. To get the schema for just error responses (400, 500) I have to do this:

$..get.responses[?(@property === '500' || @property === '400')]..schema

and what I'd like to do is something like

$..get.responses[?(@property.matches("/[45]00/"))]..schema

or similar to JayWay impl

$..get.responses[?(@property =~ /[45]00/)]..schema

{
  "paths": {
    "/path/to/service": {
      "get": {
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "required": [
                    "message"
                  ]
                }
              }
            }
          }, 
          "400": {
            "description": "request error",
            "content": {
              "application/json": {
                "schema": {
                  "required": [
                    "message"
                  ]
                }
              }
            }
          },
          "500": {
            "description": "server error",
            "content": {
              "application/json": {
                "schema": {
                  "required": [
                    "message"
                  ]
                }
              }
            }
          }
        }
      }
    }
  }
}
jeffreypriebe commented 4 years ago

Regex is supported in filters, e.g. … .responses[?(@.description.match(/ok/)]

However, it doesn't work with the @property (i.e. [?(@property.match … will just error).

Filtering using the description I think would work in your case, either of:

vitaly-magyari commented 4 years ago

@jeffreypriebe, well, I kinda want a filter by key, not by value. But thanks for the info!

jeffreypriebe commented 4 years ago

I totally get you and I tried to regex the keys but that appears to not work. I can see that being a useful addition. You up to write that feature yourself?

vitaly-magyari commented 4 years ago

@jeffreypriebe, unfortunately, no - I'm not a javascript developer, just happen to use a tool that uses this library (stoplight/spectral that is)

brettz9 commented 4 years ago

$..get.responses[?(@property.match(/[45]00/))]..schema is working for me.

e.g., adding this to tests:

it.only('filter by property', function () {
            // eslint-disable-next-line no-shadow
            const json = {
                "paths": {
                    "/path/to/service": {
                        "get": {
                            "responses": {
                                "200": {
                                    "description": "ok",
                                    "content": {
                                        "application/json": {
                                            "schema": {
                                                "required": [
                                                    "message"
                                                ]
                                            }
                                        }
                                    }
                                },
                                "400": {
                                    "description": "request error",
                                    "content": {
                                        "application/json": {
                                            "schema": {
                                                "required": [
                                                    "message"
                                                ]
                                            }
                                        }
                                    }
                                },
                                "500": {
                                    "description": "server error",
                                    "content": {
                                        "application/json": {
                                            "schema": {
                                                "required": [
                                                    "message"
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            };
            const expected = [
                json.paths['/path/to/service'].get.responses['400'].content['application/json'].schema,
                json.paths['/path/to/service'].get.responses['500'].content['application/json'].schema
            ];
            const result = jsonpath({
                json,
                path: '$..get.responses[?(@property.match(/[45]00/))]..schema'
            });
            assert.deepEqual(result, expected);
        });
brettz9 commented 4 years ago

I've added 743fd1f294a5002bb26823114334e4ac4e9ffd26 (now on master) to document this against our current examples. Closing as I think this should address. If you want a change on the syntax, I suggest looking at #124 and offering any proposals per the info there, as, given the active standardization efforts, I think we will probably only wish to add features going forward that are standardized.