orval-labs / orval

orval is able to generate client with appropriate type-signatures (TypeScript) from any valid OpenAPI v3 or Swagger v2 specification, either in yaml or json formats. 🍺
https://orval.dev
MIT License
3.02k stars 331 forks source link

Reference in referenced parameter is resolved in wrong file #394

Open bug-brain opened 2 years ago

bug-brain commented 2 years ago

What are the steps to reproduce this issue?

spec.yaml

openapi: 3.0.2
info: {}
paths:
  "/path":
    get:
      parameters:
        - $ref: "refs.yaml#/components/parameters/switch"
      responses:
        '200':
          content:
            application/json:
              schema:
                type: string

refs.yaml

components:
  schemas:
    Switch:
      type: string
      enum:
        - on
        - off
  parameters:
    switch:
      name: switch
      in: query
      schema:
        $ref: "#/components/schemas/Switch"

What happens?

Orval fails.

What were you expecting to happen?

Orval completes without errors.

Any logs, error output, etc?

🛑  backend - Oups... 🍻. Ref not found: #/components/schemas/Switch

Any other comments?

When I added another Switch schema to spec.yaml code was generated but the parameter from refs.yaml was used.

What versions are you using?

Package Version: 6.7.1

abettermap commented 2 years ago

Same issue here.

So far I have tried:

If it helps, here is my config:

// eslint-disable-next-line import/no-extraneous-dependencies
import { defineConfig } from 'orval'

import transformer from './src/lib/api/django/overrides.django'

export default defineConfig({
  'django-backend': {
    input: {
      target: './scratch/portal-api.json',
      converterOptions: true,
      override: { transformer },
    },
    output: {
      client: 'react-query',
      mock: false, // TODO
      mode: 'tags-split',
      schemas: 'src/lib/api/django/model',
      target: 'src/lib/api/django/types.django-api.ts',
      prettier: true,
      override: {
        mutator: {
          path: 'src/lib/api/django-axios-instance.ts',
          name: 'djangoAxiosInstance',
        },
      },
    },
  },
})

And my transformer:

// eslint-disable-next-line import/no-extraneous-dependencies
import { OpenAPIObject, SchemaObject } from 'openapi3-ts'

function transformer(inputSchema: OpenAPIObject): OpenAPIObject {
  const { components } = inputSchema
  const { schemas } = components || {}
  const { Field } = schemas || ({ properties: {} } as SchemaObject)

  return {
    ...inputSchema,
    components: {
      ...inputSchema.components,
      schemas: {
        ...schemas,
        Field: {
          ...Field,
          properties: {
            ...Field.properties,
            geometry: {
              oneOf: [
                // None of these work 😞
                { $ref: 'geojson-spec.yaml#/components~1schemas~1Point' },
                { $ref: 'geojson-spec.yaml#/components~1schemas~1LineString' },
                { $ref: 'geojson-spec.yaml#/components~1schemas~1Polygon' },
                { $ref: 'geojson-spec.yaml#/components~1schemas~1MultiPoint' },
                { $ref: 'geojson-spec.yaml#/components~1schemas~1MultiLineString' },
                { $ref: 'geojson-spec.yaml#/components~1schemas~1MultiPolygon' },
              ],
            },
          },
        },
      },
    },
  }
}

export default transformer

It works if I hard-code the refs:

...into the other file ('./scratch/portal-api.json' in my config above) using the oneOf syntax.

Hardcoding isn't a realistic option, of course, I just wanted to point out that orval works except for using refs in the transformer (other overrides worked fine).

I don't know enough about the source code for a PR, but I love this repo and appreciate the work so I'd be happy to troubleshoot/answer questions! Maybe it will alleviate some of the other issues that pop up in a "ref not found" search.

HugoPoi commented 7 months ago

As workaround for this you might add redocly bundle spec.yaml --ext json -o spec.json and input is the spec.json file. Orval doesn't have a hook like beforeReadSpecs but you could add a scripts command like "generate-api-clients": "redocly bundle spec.yaml --ext json -o spec.json && orval --config orval.config.ts"