UNPKG

class-validator-jsonschema

Version:

Convert class-validator-decorated classes into JSON schema

151 lines 16.2 kB
"use strict"; 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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