Fix maps generation in json-schema generator

master
Paul Loyd 2018-01-13 20:51:37 +03:00
parent a4bf88367e
commit 09f37c29bc
3 changed files with 45 additions and 15 deletions

View File

@ -1,6 +1,6 @@
import wu from 'wu';
import {invariant, collect} from '../utils';
import {invariant, collect, partition} from '../utils';
import type Fund from '../fund';
import type {Type, NumberType} from '../types';
@ -114,8 +114,29 @@ function convert(fund: Fund, type: ?Type): Schema {
anyOf: schemas,
};
case 'intersection':
return {
allOf: wu(type.parts).map(part => convert(fund, part)).toArray(),
const [maps, others] = partition(type.parts, type => type.kind === 'map');
const parts = wu(others).map(part => convert(fund, part)).toArray();
if (maps.length > 0) {
const keys = wu(maps).map(map => convert(fund, (map: $FlowFixMe).values)).toArray();
const key = keys.length === 1 ? keys[0] : {anyOf: keys};
if (parts.length === 1 && parts[0].type === 'object') {
invariant(typeof parts[0] === 'object');
invariant(parts[0].additionalProperties == null);
parts[0].additionalProperties = key;
} else {
parts.push({
type: 'object',
additionalProperties: key,
});
}
}
return parts.length === 1 ? parts[0] : {
allOf: parts,
};
case 'maybe':
return {

View File

@ -19,3 +19,13 @@ export function collect<T>(iter: Iterable<[string, T]>): {[string]: T} {
return result;
}
export function partition<T>(iter: Iterable<T>, pred: T => boolean): [T[], T[]] {
const [left, right] = [[], []];
for (const item of iter) {
(pred(item) ? left : right).push(item);
}
return [left, right];
}

View File

@ -10,20 +10,19 @@
"additionalProperties": {"type": "boolean"}
},
"maps::Couple": {
"allOf": [
{"type": "object", "additionalProperties": {"type": "boolean"}},
{"type": "object", "additionalProperties": {"type": "string"}}
]
"type": "object",
"additionalProperties": {
"anyOf": [
{"type": "boolean"},
{"type": "string"}
]
}
},
"maps::Mix": {
"allOf": [
{
"type": "object",
"properties": {"foo": {"type": "string"}},
"required": ["foo"]
},
{"type": "object", "additionalProperties": {"type": "boolean"}}
]
"type": "object",
"properties": {"foo": {"type": "string"}},
"required": ["foo"],
"additionalProperties": {"type": "boolean"}
}
}
}