swagger-js icon indicating copy to clipboard operation
swagger-js copied to clipboard

Resolving nested `allOf` keywords

Open char0n opened this issue 3 years ago • 0 comments

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 }));
})();

char0n avatar May 26 '22 11:05 char0n