openapi-generator icon indicating copy to clipboard operation
openapi-generator copied to clipboard

[BUG][Kotlin] properties title name "$and" getting compile error

Open anwarpro opened this issue 1 year ago • 4 comments

Bug Report Checklist

  • [x] Have you provided a full/minimal spec to reproduce the issue?
  • [ ] Have you validated the input using an OpenAPI validator (example)?
  • [ ] Have you tested with the latest master to confirm the issue still exists?
  • [ ] Have you searched for related issues/PRs?
  • [ ] What's the actual output vs expected output?
  • [ ] [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

properties title name "$and" getting compile error

openapi-generator version

gradle plugin 7.10.0

OpenAPI declaration file content or url
  /store/collections:
    get:
      operationId: GetCollections
      summary: List Collections
      description: Retrieve a list of collections. The collections can be filtered by fields such as `handle`. The collections can also be sorted or paginated.
      x-authenticated: false
      externalDocs:
        url: https://docs.medusajs.com/v2/resources/storefront-development/products/collections/list
        description: 'Storefront guide: How to retrieve a list of collections.'
      parameters:
        - name: fields
          in: query
          description: Comma-separated fields that should be included in the returned data. if a field is prefixed with `+` it will be added to the default fields, using `-` will remove it from the default fields. without prefix it will replace the entire default fields.
          required: false
          schema:
            type: string
            title: fields
        - name: offset
          in: query
          description: The number of items to skip when retrieving a list.
          required: false
          schema:
            type: number
            title: offset
            description: The number of items to skip when retrieving a list.
        - name: limit
          in: query
          description: Limit the number of items returned in the list.
          required: false
          schema:
            type: number
            title: limit
            description: Limit the number of items returned in the list.
        - name: order
          in: query
          description: The field to sort the data by. By default, the sort order is ascending. To change the order to descending, prefix the field name with `-`.
          required: false
          schema:
            type: string
            title: order
            description: The field to sort the data by. By default, the sort order is ascending. To change the order to descending, prefix the field name with `-`.
        - name: title
          in: query
          required: false
          schema:
            oneOf:
              - type: string
                title: title
                description: Filter by a collection's title.
              - type: array
                description: Filter by collection titles.
                items:
                  type: string
                  title: title
                  description: A title.
        - name: handle
          in: query
          required: false
          schema:
            oneOf:
              - type: string
                title: handle
                description: Filter by a collection's handle.
              - type: array
                description: Filter by collection handles.
                items:
                  type: string
                  title: handle
                  description: A handle.
        - name: q
          in: query
          description: Search term to filter the collection's searchable properties.
          required: false
          schema:
            type: string
            title: q
            description: Search term to filter the collection's searchable properties.
        - name: $and
          in: query
          description: Join query parameters with an AND condition. Each object's content is the same type as the expected query parameters.
          required: false
          schema:
            type: array
            description: Join query parameters with an AND condition. Each object's content is the same type as the expected query parameters.
            items:
              type: object
            title: $and
        - name: $or
          in: query
          description: Join query parameters with an OR condition. Each object's content is the same type as the expected query parameters.
          required: false
          schema:
            type: array
            description: Join query parameters with an OR condition. Each object's content is the same type as the expected query parameters.
            items:
              type: object
            title: $or
      tags:
        - Collections
      responses:
        '200':
          description: OK
          content:
            application/json: {}
Generation Details

generated getCollections functions body

 val localVariableAuthNames = listOf<String>()

  val localVariableBody = 
      io.ktor.client.utils.EmptyContent
  
  val localVariableQuery = mutableMapOf<String, List<String>>()
  fields?.apply { localVariableQuery["fields"] = listOf("$fields") }
  offset?.apply { localVariableQuery["offset"] = listOf("$offset") }
  limit?.apply { localVariableQuery["limit"] = listOf("$limit") }
  order?.apply { localVariableQuery["order"] = listOf("$order") }
  title?.apply { localVariableQuery["title"] = listOf("$title") }
  handle?.apply { localVariableQuery["handle"] = listOf("$handle") }
  q?.apply { localVariableQuery["q"] = listOf("$q") }
  dollarAnd?.apply { localVariableQuery["$and"] = toMultiValue(this, "multi") }
  dollarOr?.apply { localVariableQuery["$or"] = toMultiValue(this, "multi") }
  val localVariableHeaders = mutableMapOf<String, String>()
  
  val localVariableConfig = RequestConfig<kotlin.Any?>(
      RequestMethod.GET,
      "/store/collections",
      query = localVariableQuery,
      headers = localVariableHeaders,
      requiresAuthentication = false,
  )
  
  return request(
      localVariableConfig,
      localVariableBody,
      localVariableAuthNames
  ).wrap()

problem is in these lines

dollarAnd?.apply { localVariableQuery["$and"] = toMultiValue(this, "multi") }
dollarOr?.apply { localVariableQuery["$or"] = toMultiValue(this, "multi") }

localVariableQuery["$and"] should be localVariableQuery["\$and"] localVariableQuery["$or"] should be localVariableQuery["\$or"]

anwarpro avatar Jan 19 '25 07:01 anwarpro

thanks for reporting the issue

what about using the nameMappings option to workaround the issue for the time being?

https://github.com/openapitools/openapi-generator/blob/master/docs/customization.md#name-mapping

wing328 avatar Jan 20 '25 07:01 wing328

I will try to take a look at this when I have time. I see there are many places in kotlin generators where this is an issue. Basically any time it is a string, the dollar should be escaped.

Picazsoo avatar Nov 14 '25 08:11 Picazsoo

My approach would be to introduce the problematic dollar into a query param name, path param name, object property name. I will add such problematic schema to all the specs used in kotlin compile tests, so that there is no chance of regression.

Picazsoo avatar Nov 14 '25 09:11 Picazsoo

As far as kotlin-spring is concerned, I tried to do as thorough job as possible here: #22449.

Picazsoo avatar Nov 27 '25 15:11 Picazsoo