class-validator-jsonschema
Version:
Convert class-validator-decorated classes into JSON schema
151 lines • 16.2 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.targetConstructorToSchema = exports.validationMetadataArrayToSchemas = exports.validationMetadatasToSchemas = exports.JSONSchema = void 0;
const tslib_1 = require("tslib");
const cv = tslib_1.__importStar(require("class-validator"));
const lodash_groupby_1 = tslib_1.__importDefault(require("lodash.groupby"));
const lodash_merge_1 = tslib_1.__importDefault(require("lodash.merge"));
const decorators_1 = require("./decorators");
const defaultConverters_1 = require("./defaultConverters");
const options_1 = require("./options");
var decorators_2 = require("./decorators");
Object.defineProperty(exports, "JSONSchema", { enumerable: true, get: function () { return decorators_2.JSONSchema; } });
function validationMetadatasToSchemas(userOptions) {
const options = Object.assign(Object.assign({}, options_1.defaultOptions), userOptions);
const metadatas = getMetadatasFromStorage(options.classValidatorMetadataStorage);
return validationMetadataArrayToSchemas(metadatas, userOptions);
}
exports.validationMetadatasToSchemas = validationMetadatasToSchemas;
function validationMetadataArrayToSchemas(metadatas, userOptions) {
const options = Object.assign(Object.assign({}, options_1.defaultOptions), userOptions);
const schemas = {};
Object.entries((0, lodash_groupby_1.default)(metadatas, ({ target }) => {
var _a;
return (_a = target[options.schemaNameField]) !== null && _a !== void 0 ? _a : target.name;
})).forEach(([key, ownMetas]) => {
const target = ownMetas[0].target;
const metas = ownMetas
.concat(getInheritedMetadatas(target, metadatas))
.filter((propMeta) => !(isExcluded(propMeta, options) ||
isExcluded(Object.assign(Object.assign({}, propMeta), { target }), options)))
.map((propMeta) => {
var _a;
const exposeMetadata = (_a = userOptions === null || userOptions === void 0 ? void 0 : userOptions.classTransformerMetadataStorage) === null || _a === void 0 ? void 0 : _a.getExposedMetadatas(propMeta.target);
const ctMetaForField = exposeMetadata === null || exposeMetadata === void 0 ? void 0 : exposeMetadata.find((meta) => meta.propertyName === propMeta.propertyName);
if (ctMetaForField === null || ctMetaForField === void 0 ? void 0 : ctMetaForField.options.name) {
propMeta.propertyName = ctMetaForField.options.name;
}
return propMeta;
});
const properties = {};
Object.entries((0, lodash_groupby_1.default)(metas, 'propertyName')).forEach(([propName, propMetas]) => {
const schema = applyConverters(propMetas, options);
properties[propName] = applyDecorators(schema, target, options, propName);
});
const definitionSchema = {
properties,
type: 'object',
};
const required = getRequiredPropNames(target, metas, options);
if (required.length > 0) {
definitionSchema.required = required;
}
schemas[key] = applyDecorators(definitionSchema, target, options, target.name);
});
return schemas;
}
exports.validationMetadataArrayToSchemas = validationMetadataArrayToSchemas;
function getTargetConstructorSchema(schemas, targetConstructor) {
if (!targetConstructor.name) {
return {};
}
else if (schemas[targetConstructor.name]) {
return schemas[targetConstructor.name];
}
else {
return getTargetConstructorSchema(schemas, Object.getPrototypeOf(targetConstructor));
}
}
function targetConstructorToSchema(targetConstructor, userOptions) {
const options = Object.assign(Object.assign({}, options_1.defaultOptions), userOptions);
const storage = options.classValidatorMetadataStorage;
let metadatas = storage.getTargetValidationMetadatas(targetConstructor, '', true, false);
metadatas = populateMetadatasWithConstraints(storage, metadatas);
const schemas = validationMetadataArrayToSchemas(metadatas, userOptions);
return getTargetConstructorSchema(schemas, targetConstructor);
}
exports.targetConstructorToSchema = targetConstructorToSchema;
function getMetadatasFromStorage(storage) {
const metadatas = [];
for (const value of storage.validationMetadatas) {
metadatas.push(...populateMetadatasWithConstraints(storage, value[1]));
}
return metadatas;
}
function populateMetadatasWithConstraints(storage, metadatas) {
return metadatas.map((meta) => {
if (meta.constraintCls) {
const constraint = storage.getTargetValidatorConstraints(meta.constraintCls);
if (constraint.length > 0) {
return Object.assign(Object.assign({}, meta), { type: constraint[0].name });
}
}
return Object.assign({}, meta);
});
}
function getInheritedMetadatas(target, metadatas) {
return metadatas.filter((d) => d.target instanceof Function &&
target.prototype instanceof d.target &&
!metadatas.find((m) => m.propertyName === d.propertyName &&
m.target === target &&
m.type === d.type));
}
function applyConverters(propertyMetadatas, options) {
const converters = Object.assign(Object.assign({}, defaultConverters_1.defaultConverters), options.additionalConverters);
const convert = (meta) => {
var _a;
const typeMeta = (_a = options.classTransformerMetadataStorage) === null || _a === void 0 ? void 0 : _a.findTypeMetadata(meta.target, meta.propertyName);
const isMap = typeMeta &&
typeMeta.reflectedType &&
new typeMeta.reflectedType() instanceof Map;
const converter = converters[meta.type] || converters[cv.ValidationTypes.CUSTOM_VALIDATION];
const items = typeof converter === 'function' ? converter(meta, options) : converter;
if (meta.each && isMap) {
return {
additionalProperties: Object.assign({}, items),
type: 'object',
};
}
return meta.each ? { items, type: 'array' } : items;
};
return (0, lodash_merge_1.default)({}, ...propertyMetadatas.map(convert));
}
function isExcluded(propertyMetadata, options) {
var _a;
return !!((_a = options.classTransformerMetadataStorage) === null || _a === void 0 ? void 0 : _a.findExcludeMetadata(propertyMetadata.target, propertyMetadata.propertyName));
}
function applyDecorators(schema, target, options, propertyName) {
const additionalSchema = (0, decorators_1.getMetadataSchema)(target.prototype, propertyName);
return typeof additionalSchema === 'function'
? additionalSchema(schema, options)
: (0, lodash_merge_1.default)({}, schema, additionalSchema);
}
function getRequiredPropNames(target, metadatas, options) {
function isDefined(metas) {
return (metas && metas.some(({ type }) => type === cv.ValidationTypes.IS_DEFINED));
}
function isOptional(metas) {
return (metas &&
metas.some(({ type }) => [cv.ValidationTypes.CONDITIONAL_VALIDATION, cv.IS_EMPTY].includes(type)));
}
return Object.entries((0, lodash_groupby_1.default)(metadatas, (m) => m.propertyName))
.filter(([_, metas]) => {
const own = metas.filter((m) => m.target === target);
const inherited = metas.filter((m) => m.target !== target);
return options.skipMissingProperties
? isDefined(own) || (!isOptional(own) && isDefined(inherited))
: !(isOptional(own) || isOptional(inherited));
})
.map(([name]) => name);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUNBLDREQUFxQztBQUVyQyw0RUFBcUM7QUFDckMsd0VBQWlDO0FBR2pDLDZDQUFnRDtBQUNoRCwyREFBdUQ7QUFDdkQsdUNBQW9EO0FBR3BELDJDQUF5QztBQUFoQyx3R0FBQSxVQUFVLE9BQUE7QUFTbkIsU0FBZ0IsNEJBQTRCLENBQzFDLFdBQStCO0lBRS9CLE1BQU0sT0FBTyxtQ0FDUix3QkFBYyxHQUNkLFdBQVcsQ0FDZixDQUFBO0lBRUQsTUFBTSxTQUFTLEdBQUcsdUJBQXVCLENBQ3ZDLE9BQU8sQ0FBQyw2QkFBNkIsQ0FDdEMsQ0FBQTtJQUVELE9BQU8sZ0NBQWdDLENBQUMsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUFBO0FBQ2pFLENBQUM7QUFiRCxvRUFhQztBQUtELFNBQWdCLGdDQUFnQyxDQUM5QyxTQUErQixFQUMvQixXQUErQjtJQUUvQixNQUFNLE9BQU8sbUNBQ1Isd0JBQWMsR0FDZCxXQUFXLENBQ2YsQ0FBQTtJQUVELE1BQU0sT0FBTyxHQUFvQyxFQUFFLENBQUE7SUFDbkQsTUFBTSxDQUFDLE9BQU8sQ0FDWixJQUFBLHdCQUFRLEVBQ04sU0FBUyxFQUNULENBQUMsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFOztRQUNiLE9BQUEsTUFBQSxNQUFNLENBQUMsT0FBTyxDQUFDLGVBQXNDLENBQUMsbUNBQ3JELE1BQW1CLENBQUMsSUFBSSxDQUFBO0tBQUEsQ0FDNUIsQ0FDRixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxFQUFFLEVBQUU7UUFDNUIsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQWtCLENBQUE7UUFDN0MsTUFBTSxLQUFLLEdBQUcsUUFBUTthQUNuQixNQUFNLENBQUMscUJBQXFCLENBQUMsTUFBTSxFQUFFLFNBQVMs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
;