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 wu from 'wu';
import {invariant, collect} from '../utils'; import {invariant, collect, partition} from '../utils';
import type Fund from '../fund'; import type Fund from '../fund';
import type {Type, NumberType} from '../types'; import type {Type, NumberType} from '../types';
@ -114,8 +114,29 @@ function convert(fund: Fund, type: ?Type): Schema {
anyOf: schemas, anyOf: schemas,
}; };
case 'intersection': case 'intersection':
return { const [maps, others] = partition(type.parts, type => type.kind === 'map');
allOf: wu(type.parts).map(part => convert(fund, part)).toArray(),
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': case 'maybe':
return { return {

View File

@ -19,3 +19,13 @@ export function collect<T>(iter: Iterable<[string, T]>): {[string]: T} {
return result; 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"} "additionalProperties": {"type": "boolean"}
}, },
"maps::Couple": { "maps::Couple": {
"allOf": [ "type": "object",
{"type": "object", "additionalProperties": {"type": "boolean"}}, "additionalProperties": {
{"type": "object", "additionalProperties": {"type": "string"}} "anyOf": [
] {"type": "boolean"},
{"type": "string"}
]
}
}, },
"maps::Mix": { "maps::Mix": {
"allOf": [ "type": "object",
{ "properties": {"foo": {"type": "string"}},
"type": "object", "required": ["foo"],
"properties": {"foo": {"type": "string"}}, "additionalProperties": {"type": "boolean"}
"required": ["foo"]
},
{"type": "object", "additionalProperties": {"type": "boolean"}}
]
} }
} }
} }