json-schema-to-joi
Version:
Converts JSON schema to Joi typescript code
166 lines • 6.25 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveJSONSchema = exports.resolveBundledJSONSchema = void 0;
const resolveType_1 = require("./resolveType");
const alternatives_1 = require("./alternatives");
const _ = require("lodash");
const oneOf_1 = require("./oneOf");
const allOf_1 = require("./allOf");
function resolveBundledJSONSchema(definitions, options) {
const ret = [];
const map = new Map();
let keyOnList = [];
const keyDone = [];
if (definitions) {
_.forIn(definitions, (subSchema, key) => {
const joiSchema = resolveJSONSchema(subSchema, options);
joiSchema.label = _.camelCase(key);
map.set(joiSchema.label, {
joiSchema,
dependencies: extractDependency(joiSchema),
});
keyOnList.push(joiSchema.label);
});
const useDeprecatedJoi = options ? options.useDeprecatedJoi : false;
while (keyOnList.length > 0) {
const keysToBeRemoved = [];
map.forEach((value, key) => {
value.dependencies = value.dependencies.filter((v) => keyDone.indexOf(v) === -1);
if (value.dependencies.length === 0 ||
(value.dependencies.length === 1 && _.camelCase(value.dependencies[0]) === key)) {
if (value.dependencies.length === 1) {
replaceRecursiveReference(value.joiSchema, key, useDeprecatedJoi);
if (!useDeprecatedJoi) {
value.joiSchema.id = key;
}
}
ret.push(value.joiSchema);
keyDone.push(key);
keyOnList = keyOnList.filter((v) => v !== key);
keysToBeRemoved.push(key);
}
});
keysToBeRemoved.forEach((key) => {
map.delete(key);
});
}
}
return ret;
}
exports.resolveBundledJSONSchema = resolveBundledJSONSchema;
function replaceRecursiveReference(joiSchema, key, useDeprecatedJoi = false) {
if ((joiSchema.type === 'reference' && joiSchema.$ref === key)) {
joiSchema.type = useDeprecatedJoi ? 'lazy' : 'link';
}
_.forIn(joiSchema, (value) => {
if (_.isArray(value)) {
value.forEach((item) => {
replaceRecursiveReference(item, key, useDeprecatedJoi);
});
}
else if (_.isObject(value)) {
replaceRecursiveReference(value, key, useDeprecatedJoi);
}
});
}
function extractDependency(joiSchema) {
const ret = [];
if (joiSchema.type === 'reference' && joiSchema.$ref) {
ret.push(_.camelCase(joiSchema.$ref));
}
_.forIn(joiSchema, (value) => {
if (_.isArray(value)) {
value.forEach((item) => {
ret.push(...extractDependency(item));
});
}
else if (_.isObject(value)) {
ret.push(...extractDependency(value));
}
});
return ret;
}
function resolveJSONSchema(schema, options) {
const realOptions = _.defaults(options, {
useDeprecatedJoi: false,
useExtendedJoi: false,
});
if (schema.$ref) {
const $ref = schema.$ref;
const standardJsonSchema = $ref.startsWith('#/definitions');
const paths = $ref.split('/');
if ((standardJsonSchema && paths.length === 3)
|| (!standardJsonSchema && paths.length === 4)) {
return {
type: 'reference',
$ref: _.camelCase(paths[standardJsonSchema ? 2 : 3]),
label: schema.title,
description: schema.description,
};
}
const rootSchema = realOptions.rootSchema ? realOptions.rootSchema : schema;
return resolveJSONSchema(_.get(rootSchema, paths.slice(1).join('.')), options);
}
if (schema.enum && !schema.type && !schema.format) {
return {
type: 'any',
valid: schema.enum,
label: schema.title,
description: schema.description,
};
}
if (schema.anyOf || schema.not) {
return alternatives_1.resolveJoiAlternativesSchema(schema, realOptions);
}
if (schema.allOf || schema.oneOf) {
if (realOptions.useDeprecatedJoi && realOptions.useExtendedJoi) {
if (schema.allOf) {
return allOf_1.resolveJoiAllOfSchema(schema, options);
}
else {
return oneOf_1.resolveJoiOneOfSchema(schema, options);
}
}
else {
return alternatives_1.resolveJoiAlternativesSchema(schema, realOptions);
}
}
if (_.isArray(schema.type) && schema.type.length > 0) {
return resolveJSONSchema({
anyOf: schema.type.map((type) => {
return { type, };
}),
});
}
if (!schema.type) {
if (schema.required !== undefined || schema.properties
|| schema.patternProperties || schema.dependencies
|| _.isNumber(schema.minProperties) || _.isNumber(schema.maxProperties)) {
schema.type = 'object';
}
else if (schema.items || _.isNumber(schema.minItems) || _.isNumber(schema.maxItems)
|| schema.uniqueItems || schema.additionalItems) {
schema.type = 'array';
}
else if (_.isNumber(schema.minLength) || _.isNumber(schema.maxLength) || schema.pattern) {
schema.type = 'string';
}
else if (_.isNumber(schema.multipleOf)
|| _.isNumber(schema.minimum) || _.isNumber(schema.maximum)) {
schema.type = 'number';
}
else if (schema.format && [
'date-time', 'date', 'time', 'email',
'hostname', 'ipv4', 'ipv6', 'uri',
'byte', 'binary', 'uuid', 'guid',
].includes(schema.format)) {
schema.type = 'string';
}
else {
schema.type = 'any';
}
}
return resolveType_1.resolveType(schema, realOptions);
}
exports.resolveJSONSchema = resolveJSONSchema;
//# sourceMappingURL=resolve.js.map
;