swagger-js
swagger-js copied to clipboard
Resolving nested `allOf` keywords
When resolving subtree with nested allOf keywords, allOf and $ref keywords are not resolved on all places.
The problem manifests only when resolution is done on subtree of the definition (not the whole one). In 99% cases the resolution of subtree works, but on some definitions which are written in a certain way, nested JSON Schema objects within the subtree are untouched by resolution and allOf + $ref is not processed/traversed at all. This creates multitude of side effects which manifests like errors.
OAS definition to reproduce - str.yaml
# OpenAPI version identifier - required for OpenAPI 3.0 domains
openapi: 3.0.3
#######################
# Optional info section
#######################
info:
title: Steps To Reproduce
version: 2.0.0
components:
schemas:
schemaStub1: {
type: object
}
shippingInstructionRequest:
type: object
allOf:
- $ref: '#/components/schemas/shippingInstructionShallow'
- $ref: '#/components/schemas/shippingInstructionDeep'
shippingInstructionShallow:
type: object
allOf:
- type: object
properties:
amendToTransportDocument:
allOf:
- $ref: '#/components/schemas/schemaStub1'
shippingInstructionDeep:
type: object
allOf:
- type: object
properties:
placeOfIssue:
allOf:
- $ref: '#/components/schemas/schemaStub1'
shippingInstructionResponse:
type: object
allOf:
- $ref: '#/components/schemas/shippingInstructionRequest'
transportDocument:
allOf:
- properties:
shippingInstruction:
allOf:
- $ref: '#/components/schemas/shippingInstructionResponse'
Failing JavaScript test:
const fs = require('fs');
const yaml = require('js-yaml');
const { inspect } = require('util');
const yamlObj = yaml.load(fs.readFileSync('./str.yaml'));
const { default: SwaggerClient } = require('swagger-client');
(async () => {
const result = await SwaggerClient.resolveSubtree(
yamlObj,
['components', 'schemas', 'transportDocument'],
{ returnEntireTree: true }
);
console.log(inspect(result, { showHidden: true, depth: null }));
})();
Expected result can be seen by running following code:
const fs = require('fs');
const yaml = require('js-yaml');
const { inspect } = require('util');
const yamlObj = yaml.load(fs.readFileSync('./str.yaml'));
const { default: SwaggerClient } = require('swagger-client');
(async () => {
const result = await SwaggerClient.resolve({ spec: yamlObj });
console.log(inspect(result, { showHidden: true, depth: null }));
})();