extends: spectral:oas 
functions:
  - expectServersConfig
  - infoLicenseApache2
  - schemaDefinition

rules:
  openapi-tags: off
  operation-tags: off
  oas3-valid-schema-example: warn
  no-$ref-siblings: warn
  oas3-valid-media-example: warn

  rhoas-oas3minimum:
    given: "$"
    description: OpenAPI version must be >= 3
    recommended: true
    severity: warn
    then:
      field: openapi
      function: pattern
      functionOptions:
        match: 3.[0-9]?.[0-9]
  rhoas-servers-config:
    given: "$"
    severity: warn
    recommended: true
    then:
      function: expectServersConfig
      field: servers
      functionOptions:
        required:
          - https://api.openshift.com
          - https://api.stage.openshift.com
          - http://localhost:8000
          - "/"
  rhoas-info-license-apache2.0:
    severity: error
    recommended: true
    given: "$"
    then:
      function: infoLicenseApache2
      field: info.license
  rhoas-path-regexp:
    given: "$.paths[*]~"
    severity: warn
    description:
      OpenAPI paths must start with `/api/`, followed by a version. All paths
      must follow snake_case
    then:
      function: pattern
      functionOptions:
        match: "\/api\/([a-z_]*){1,}(\/v[0-9]*(alpha|beta)?)(\/{?[a-z_]*}?){0,}$"
  rhoas-response-media-type:
    given: "$.paths.*.*.responses.*.content"
    description: application/json is the only acceptable content type
    severity: warn
    then:
      function: truthy
      field: application/json
  rhoas-error-response:
    given: "$.paths..responses[?( @property >= 300)].content.*"
    severity:  warn
    then:
      field: schema
      function: schema
      functionOptions:
        schema:
          "$ref": "#/components/schemas/Error"
  rhoas-object-resource-schema:
    given: "$.paths..responses[?( @property < 300)].content.*"
    severity: warn 
    then:
      function: schema
      field: schema
      functionOptions:
        schema:
          "$ref": "#/components/schemas/ObjectReference"
  rhoas-schema-name-pascal-case:
    description: JSON Schema names should use PascalCase
    message: "`{{property}}` object name must follow PascalCase"
    severity: error
    given: "$.components.schemas[*]~"
    then:
      function: pattern
      functionOptions:
        match: "^([A-Z]{1}[a-z]{1,}){1,}$"
  rhoas-schema-properties-snake-case:
    description:
      All JSON Schema properties MUST follow snake_case and be ASCII alphanumeric
      characters.
    severity: error
    recommended: true
    message: "`{{property}}` MUST follow snake_case and be ASCII alphanumeric characters."
    given: "$.components.schemas..properties[*]~"
    then:
      function: pattern
      functionOptions:
        match: "/^[a-z0-9_]{1,}/"
  rhoas-error-schema:
    severity: warn
    recommended: true
    given: "$.components.schemas"
    then:
      function: schemaDefinition
      field: Error
      functionOptions:
        definition:
          type: object
          properties:
            code:
              type: string
              required: true
            id:
              type: string
              required: true
            href:
              type: string
              required: true
            reason:
              type: string
              required: true
  rhoas-object-schema:
    severity: warn
    recommended: true
    given: "$.components.schemas"
    then:
      function: schemaDefinition
      field: ObjectReference
      functionOptions:
        definition:
          type: object
          properties:
            id:
              type: string
              required: true
            kind:
              type: string
              required: true
            href:
              type: string
              required: true
  rhoas-list-schema:
    severity: warn
    recommended: true
    given: "$.components.schemas"
    then:
      function: schemaDefinition
      field: List
      functionOptions:
        definition:
          type: object
          properties:
            items:
              type: array
              required: true
            kind:
              type: string
              required: true
            page:
              type: integer
              required: true
            size:
              type: integer
              required: true
            total:
              type: integer
              required: true
  rhoas-operaton-id:
    severity: warn
    recommended: true
    given: "$.paths.*.*"
    then:
      function: truthy
      field: operationId