@decaf-ts/decorator-validation
Version:
simple decorator based validation engine
130 lines • 5.86 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
require("./Metadata.cjs");
const decoration_1 = require("@decaf-ts/decoration");
const Model_1 = require("./../model/Model.cjs");
const constants_1 = require("./../validation/Validators/constants.cjs");
const constants_2 = require("./../model/constants.cjs");
const ModelRegistry_1 = require("./../model/ModelRegistry.cjs");
decoration_1.Metadata.validationFor = function (model, property, key) {
const meta = decoration_1.Metadata.get(model);
if (!meta)
return undefined;
if (!property)
return meta.validation;
if (!meta.validation)
return undefined;
if (!meta.validation[constants_1.ValidationKeys.TYPE]) {
const { designTypes } = decoration_1.Metadata.getPropDesignTypes(model, property);
// Adds by default the type validation
// If the designtypes is object, we exclude it. It causes problems with pks.
if (meta.validation[property] &&
designTypes?.length &&
designTypes[0] !== constants_2.ReservedModels.OBJECT)
meta.validation[property][constants_1.ValidationKeys.TYPE] = {
customTypes: designTypes,
message: constants_1.DEFAULT_ERROR_MESSAGES.TYPE,
description: "defines the accepted types for the attribute",
async: false,
};
}
if (!key) {
const validationsForProp = meta.validation[property];
return validationsForProp;
}
const propValidation = meta.validation[property];
if (!propValidation)
return undefined;
return propValidation[key];
}.bind(decoration_1.Metadata);
decoration_1.Metadata.modelName = function (model) {
const constr = decoration_1.Metadata.constr(model);
return constr ? constr.name : model.name;
}.bind(decoration_1.Metadata);
decoration_1.Metadata.validatableProperties = function (model, ...propsToIgnore) {
const metavalidation = decoration_1.Metadata.validationFor(model);
const keys = metavalidation ? Object.keys(metavalidation) : [];
const props = [...new Set([...Model_1.Model.getAttributes(model), ...keys])];
return props.filter((k) => !propsToIgnore || !propsToIgnore?.includes(k));
}.bind(decoration_1.Metadata);
decoration_1.Metadata.allowedTypes = function (model, prop) {
const designType = decoration_1.Metadata.type(model, prop);
if (!designType)
throw new Error(`No metadata found for property ${String(prop)}`);
const validation = decoration_1.Metadata.validationFor(model, prop);
// TODO: CHeck why some are not iterable
return validation &&
validation[constants_1.ValidationKeys.TYPE] &&
typeof validation[constants_1.ValidationKeys.TYPE]?.customTypes[Symbol.iterator] ===
"function"
? [...validation[constants_1.ValidationKeys.TYPE].customTypes]
: [designType];
}.bind(decoration_1.Metadata);
decoration_1.Metadata.getPropDesignTypes = function (model, prop) {
const metadata = decoration_1.Metadata.get(model);
const designTypeMeta = decoration_1.Metadata.type(model, prop);
const validation = metadata?.[constants_1.ValidationKeys.REFLECT]?.[prop];
if (!designTypeMeta && (!validation || !validation[constants_1.ValidationKeys.TYPE]))
return {};
const propTypes = validation && validation[constants_1.ValidationKeys.TYPE]
? [validation[constants_1.ValidationKeys.TYPE].customTypes]
: [designTypeMeta];
if (!propTypes?.length)
return {};
const designTypeDec = propTypes[0];
const designType = designTypeDec.class ||
designTypeDec.clazz ||
designTypeDec.customTypes ||
designTypeDec;
const designTypes = (Array.isArray(designType) ? designType : [designType]).map((e) => (e = typeof e === "function" && !e.name ? e() : e));
return { designTypes, designType };
}.bind(decoration_1.Metadata);
decoration_1.Metadata.isModel = function isModel(target) {
try {
if (target instanceof Model_1.Model)
return true;
const constr = decoration_1.Metadata.constr(target);
if (!constr || constr === target)
return false;
return !!decoration_1.Metadata.modelName(constr);
//
// // return target instanceof Model || !!Metadata.modelName(target as any);
// const modelName = Metadata.modelName(target as any);
// return target instanceof Model || !!Model.get(modelName);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
}
catch (e) {
return false;
}
}.bind(decoration_1.Metadata);
decoration_1.Metadata.isPropertyModel = function isPropertyModel(target, attribute) {
const isModel = decoration_1.Metadata.isModel(target[attribute]);
if (isModel)
return true;
const metadata = decoration_1.Metadata.type(target.constructor, attribute);
if (!metadata)
return undefined;
return ModelRegistry_1.ModelRegistryManager.getRegistry().get(metadata.name)
? metadata.name
: undefined;
}.bind(decoration_1.Metadata);
decoration_1.Metadata.getAttributes = function getAttributes(model) {
const constructor = model instanceof Model_1.Model ? model.constructor : model;
const seen = new Set();
const collect = (current) => {
if (!current)
return [];
const parent = Object.getPrototypeOf(current);
const attributes = collect(parent);
const props = decoration_1.Metadata.properties(current) ?? [];
for (const prop of props) {
if (!seen.has(prop)) {
seen.add(prop);
attributes.push(prop);
}
}
return attributes;
};
return collect(constructor);
}.bind(decoration_1.Metadata);
//# sourceMappingURL=overrides.js.map