openapi-typescript-codegen
openapi-typescript-codegen copied to clipboard
Sub-refs in external refs results in incorrect and broken imports in generated models
Using a ref to refer to an object in a secondary file, that also uses refs to refer to other sibling objects results in strange incorrect imports in generated models.
For example, given the following spec:
# spec.yaml
components:
schemas:
LocalParent:
$ref: './types.yaml#/components/schemas/Parent'
and the following secondary file:
# types.yaml
components:
schemas:
Parent:
type: object
properties:
childA:
$ref: '#/components/schemas/Child'
childB:
$ref: '#/components/schemas/Child'
Child:
type: string
Results in the following model with an import referencing a non-existent file:
# LocalParent.ts
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { LocalParent_properties_childA } from './LocalParent_properties_childA';
export type LocalParent = {
childA?: string;
childB?: LocalParent_properties_childA;
};
I'd like to resolve this myself, but have no idea where to start - I looked into the ref parser, but it seems to be returning a correct inventory. If you could nudge me in the right direction, I'm happy to do the legwork.
Thanks @ferdikoomen !
After further investigation, I'm now sus on the remapping that occurs in the json-schema-ref-parser - it seems to dereference external refs differently to internal ones, and returns $ref pointers to specific fields rather than inventory entities. It might be correct for that project, but isn't handled correctly by the getModel function that isn't expecting a $ref to a field.
Would a potential solution be to add another branch to the if (definition.$ref)
case in getModel to handle this? I feel like the answer is probably no, because by this time the model in question has already been dereferenced and remapped by json-schema-ref-parser and isn't available.
I feel like the solution is probably in json-schema-ref-parser. Add some mechanism to stop it remapping externals so differently? Not sure 🤷
+1 I'm getting the same issue with nested referenced schemas.
@caseyfw @ritchieanesco this sounds like a json-schema-ref-parser
issue. Did you try to reproduce the result there. You should be able to do something like this in a simple NodeJS script:
const RefParser = require('json-schema-ref-parser');
const file = 'mySpec.json';
RefParser.bundle(file, file, {}).then(spec => {
console.log(spec);
});
And see the resulting spec file (dereferenced and remapped)
Docs for the bundle method: https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#bundleschema-options-callback