swagger-js
swagger-js copied to clipboard
[Bug] Caching $ref issue with multiple files
The same pointers in different files cause mutations not being applied. The problem is in these lines of code: https://github.com/swagger-api/swagger-js/blob/master/src/specmap/index.js#L114-L130
obj.$$ref doesn't include file info and the same pointers in different files are treated as the same one.
One of the results - allOf isn't expanded and swagger-ui does't display sub-items. (see response on the screenshot)
As a quick and dirty workaround for those who are affected: either cache can be disabled or allOf can be expanded in swagger-ui.
The problem is that there is no info from which file the pointer comes inside the traverse function, so such info should be passed there in some way to make the pointer unique and avoid false cache hits. I'm not so familiar with the code, so I can't select the proper way to pass such info, I see a few options:
- $$ref should always contain file, which doesn't seem a correct way to me
- mutation should always have additional parameter with file info
- context has to be passed in some way
With the decision I can prepare the fix and the tests.
Screenshot:

The simplified example from a real case(which has more than 1 element in allOf and oneOf):
requests.yml
components:
schemas:
Object:
title: Request
type: object
required:
- param
properties:
param:
$ref: "#/components/schemas/Param"
example:
param:
name: qqq
number: 3
Param:
oneOf:
- $ref: "#/components/schemas/SubParam"
SubParam:
allOf:
- properties:
name:
type: string
example: qqq
- properties:
number:
type: integer
example: 3
responses.yml
components:
schemas:
Object:
title: Response
type: object
required:
- param
properties:
param:
$ref: "#/components/schemas/Param"
example:
param:
slug: zzz
id: 1
Param:
oneOf:
- $ref: "#/components/schemas/SubParam"
SubParam:
allOf:
- properties:
slug:
type: string
example: zzz
- properties:
id:
type: integer
example: 3
api.yml
openapi: "3.0.0"
paths:
/broken:
post:
requestBody:
required: true
content:
application/json:
schema:
$ref: "requests.yml#/components/schemas/Object"
responses:
200:
description: ''
content:
application/json:
schema:
$ref: "responses.yml#/components/schemas/Object"
Yep, this is a bug.
We compute fully-qualified pointers elsewhere in the $ref plugin; using those here would probably solve this.