redocly-cli icon indicating copy to clipboard operation
redocly-cli copied to clipboard

Configurable rules: can't target named schema in subject

Open samanthawritescode opened this issue 1 year ago • 6 comments

Motivation I'm ultimately to write a configurable rule to check that all SchemaProperties are in kebab-case with some exceptions. I thought that I could do this by using some combination of where and filterInParentKeys, but I'm running into unexpected issues. I'm not sure if it's a bug or my misunderstanding.

Here's a pared down version of my schema, defined under components.schemas as a named schema:

MySchema:
  type: object
  properties:
    id:
      type: string
    badKeyA:
      type: object
      properties:
        valid-key-a:
          type: object
          properties:
            valid-key-b:
              type: string
            headers:
              type: object
              properties:
                Accept:
                  type: string
                User-Agent:
                  type: string
            badKeyC:
              type: string
        badKeyB:
          type: string
          format: date-time

I'd like to write a rule to validate that every schema property in my entire spec is in kebab-case except anything under headers for this specific schema only.

Attempts and Issues

So, to start, this "works", in the sense that it doesn't return a validation error for the Accept or User-Agent properties and it does return one for all the badKeys.

  rule/my-schema-kebab-case:
    where:
      - subject:
          type: Schema
          filterOutParentKeys:
            - headers
        assertions:
          defined: true
    subject:
      type: SchemaProperties
    assertions:
      casing: kebab-case

However, what if I have header keys in other schemas that I do want to validate case within? So, I attempted to write a rule that targeted only MySchema:

  rule/my-schema-kebab-case:
    where:
      - subject:
          type: Schema
          filterInParentKeys:
            - MySchema
        assertions:
          defined: true
    subject:
      type: SchemaProperties
    assertions:
      casing: kebab-case

This, inexplicably to me, does not work. Running lint says my schema is valid. However, running lint with this rule (changing MySchema to badKey), tells me that badKeyB is invalid:

  rule/my-schema-kebab-case:
    where:
      - subject:
          type: Schema
          filterInParentKeys:
            - badKey
        assertions:
          defined: true
    subject:
      type: SchemaProperties
    assertions:
      casing: kebab-case

Expected behavior

Since the node type for MySchema and badKey are both Schema, I would expect targeting MySchema as a parent key to work similar to how I can target badKey. In the case where I filter by the parent key MySchema, I would expect the output of lint to at least tell me that badKey is invalid.

OpenAPI version 3.1.0

Redocly Version(s) 1.2.0

Node.js Version(s) v16.15.1

Additional Notes I tried to keep this mostly focused on the one problem of not being able to target MySchema as a parent key, but I would greatly appreciate any general help on writing the rule(s) that I ultimately want!

samanthawritescode avatar Oct 17 '23 23:10 samanthawritescode

Hi @samanthawritescode! Thanks for sharing your case.

Are you sure your second attempt doesn't work? I checked your example, and lint shows me an error on badKeyA. And if I change MySchema to badKeyA, it's erroring on badKeyB.

Lint only checks the first SchemaProperties level under the Schema that fits the where condition. It doesn't track any nested properties in nested schemas because the schemas don't align with the where section.

Also, have you considered adding the exception to .redocly.lint-ignore.yaml file so you don't have to use the where?

tatomyr avatar Oct 18 '23 12:10 tatomyr

Hi @tatomyr thanks for your quick response!

I just retried the second attempt and it still does not work. I have that schema out in a different file and referenced via #ref elsewhere in the spec, so I bundled my spec and ran it on the bundled file as well, no luck.

I don't know if it makes me feel better or worse that you can't reproduce it 😅

As far as the ignore file, that's exactly what I should be doing, thank you! I'm new to OpenAPI and redocly and haven't gotten a full handle on all the features yet.

samanthawritescode avatar Oct 18 '23 19:10 samanthawritescode

Is this what you expect to be highlighted with the second rule?

Screenshot 2023-10-19 at 10 14 05

I have that schema out in a different file and referenced via #ref elsewhere in the spec

Might it be that there are broken/incorrect/multiple references to that schema? Any misspelled words?

tatomyr avatar Oct 19 '23 07:10 tatomyr

Yes, exactly.

I've checked for misspelled words. There are multiple references to that schema, but I've validated that they're not broken or otherwise incorrect. Is it an issue if there are multiple references to it?

samanthawritescode avatar Oct 19 '23 19:10 samanthawritescode

Is it an issue if there are multiple references to it?

Not at all! It just might happen that it is referenced in a way that somehow changes the lint behaviour. E. g. your Schema is actually referenced as a SchemaProperty (I’m just trying to guess 😅), so the $ref itself is correct, but the node type changes (and the rule does not work). Could you turn this rule on: https://redocly.com/docs/cli/rules/spec-strict-refs/#spec-strict-refs ? Does it complain?

Also, could you run your example in isolation like I did (see my screenshot above)? If it still differs, it must be a bug on our end. If not - something is with your API description and you might need to make another sample to reproduce the error.

tatomyr avatar Oct 20 '23 04:10 tatomyr

@samanthawritescode any updates on this? Is there still the issue?

tatomyr avatar Jan 04 '24 15:01 tatomyr