fix: visit and bundle discriminator mappings (#90)

This commit is contained in:
Roman Hotsiy
2020-01-15 11:34:27 +02:00
committed by GitHub
parent 5c69504473
commit 43a92bd0df
4 changed files with 45 additions and 4 deletions

View File

@@ -92,6 +92,11 @@ function traverseNode(node, definition, ctx, visited = []) {
const resolvedDefinition = resolveDefinition(definition, ctx, nodeContext.resolvedNode);
resolveScalars(nodeContext.resolvedNode, definition, ctx);
if (definition.customResolveFields) {
definition.customResolveFields(nodeContext.resolvedNode, ctx, visited);
}
if (Array.isArray(nodeContext.resolvedNode)) {
nodeContext.resolvedNode.forEach((nodeChild, i) => {
ctx.path.push(i);

View File

@@ -1,3 +1,9 @@
/* eslint-disable import/no-cycle */
import traverseNode from '../traverse';
import OpenAPISchema from './OpenAPISchema';
export const MAPPING_DATA_KEY = 'x-openapiCli_resolveMappingData';
export default {
name: 'OpenAPIDiscriminator',
isIdempotent: true,
@@ -5,4 +11,26 @@ export default {
propertyName: null,
mapping: null,
},
customResolveFields: (node, ctx, visited) => {
if (node && node.mapping && typeof node.mapping === 'object') {
ctx.path.push('mapping');
for (const key of Object.keys(node.mapping)) {
ctx.path.push(key);
traverseNode(
{
$ref: node.mapping[key],
[MAPPING_DATA_KEY]: { // FIXME: too hacky
mapping: node.mapping,
key,
},
},
OpenAPISchema,
ctx,
visited,
);
ctx.path.pop();
}
ctx.path.pop();
}
},
};

View File

@@ -8,6 +8,7 @@ import isEqual from 'lodash.isequal';
import { getMsgLevelFromString, messageLevels } from '../error/default';
import OpenAPISchemaObject from '../types/OpenAPISchema';
import { MAPPING_DATA_KEY } from '../types/OpenAPIDiscriminator';
import { isRef } from '../utils';
const getComponentName = (refString, components, componentType, node, ctx) => {
@@ -90,7 +91,7 @@ class Bundler {
const $ref = `#/${pointer.join('/')}`;
const errors = [];
for (const [name, schema] of Object.entries(schemas)) {
for (const [name, schema] of Object.entries(schemas || {})) {
if (schema.allOf && schema.allOf.find((s) => s.$ref === $ref)) {
const existingSchema = this.components.schemas && this.components.schemas[name];
if (existingSchema && !isEqual(existingSchema, schema)) {
@@ -123,7 +124,7 @@ class Bundler {
onExit: (node, definition, ctx, unresolvedNode, { traverseNode, visited }) => {
let errors = [];
if (node.discriminator && !node.oneOf && !node.anyOf) {
if (node.discriminator && !node.oneOf && !node.anyOf && !node.mapping) {
errors = this.includeImplicitDiscriminator(
ctx.path,
ctx.document.components && ctx.document.components.schemas,
@@ -153,9 +154,15 @@ class Bundler {
}
this.components[componentType][name] = node;
if (unresolvedNode[MAPPING_DATA_KEY]) { // FIXME: too hack
const { mapping, key } = unresolvedNode[MAPPING_DATA_KEY];
mapping[key] = newRef;
} else {
unresolvedNode.$ref = newRef;
}
}
}
errors.forEach((e) => {
e.severity = this.nameConflictsSeverity;

View File

@@ -1,4 +1,5 @@
import fs from 'fs';
import { MAPPING_DATA_KEY } from '../../../types/OpenAPIDiscriminator';
class NoRefSiblings {
static get rule() {
@@ -29,7 +30,7 @@ class NoRefSiblings {
ctx.source = fs.readFileSync(prevPathItem.file, 'utf-8');
for (let i = 0; i < nodeKeys.length; i++) {
if (nodeKeys[i] !== '$ref') {
if (nodeKeys[i] !== '$ref' && nodeKeys[i] !== MAPPING_DATA_KEY) {
ctx.path.push(nodeKeys[i]);
const e = ctx.createError(
'No siblings are allowed inside object with $ref property.',