Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
sequelize-joi validation helper
const getFixedModelName = (modelName) => {
if (models[modelName]) return modelName;
return modelName.slice(0, -1);
};
const getModelFilterSchema = (modelName) => {
const modelWhereAttrs = {};
const modelAttrs = models[modelName].attributes;
for (let attr in modelAttrs) {
if (modelAttrs[attr].joiFilter)
modelWhereAttrs[attr] = modelAttrs[attr].joiFilter;
}
return modelWhereAttrs;
};
const getModelValidationSchema = (modelName) => {
const whereAttrs = {};
const model = models[modelName];
const modelAttrs = model.attributes;
const modelAssociations = Object.keys(model.associations),
modelRawAttrs = Object.keys(model.rawAttributes);
for (let attr in modelAttrs) {
if (modelAttrs[attr].joiFilter)
whereAttrs[attr] = modelAttrs[attr].joiFilter;
}
let incAttrWhen;
if (modelAssociations.length > 0) {
let modelName = getFixedModelName(modelAssociations[0]);
incAttrWhen = joi.when("association", {
"is": modelAssociations[0],
"then": joi.string().valid(Object.keys(models[modelAssociations[0]].rawAttributes))
});
for (let i = 1; i < modelAssociations.length; i++) {
modelName = getFixedModelName(modelAssociations[i]);
incAttrWhen.when("association", {
"is": modelAssociations[i],
"then": joi.string().valid(Object.keys(models[modelName].rawAttributes))
})
}
}
let incWhereWhen;
if (modelAssociations.length > 0) {
let modelName = getFixedModelName(modelAssociations[0]);
incWhereWhen = joi.when("association", {
"is": modelAssociations[0],
"then": getModelFilterSchema(modelName)
});
for (let i = 1; i < modelAssociations.length; i++) {
modelName = getFixedModelName(modelAssociations[i]);
incWhereWhen.when("association", {
"is": modelAssociations[i],
"then": getModelFilterSchema(modelName)
})
}
}
let incSchema;
// console.log(JSON.stringify(incAttrWhen));
if (modelAssociations.length) {
incSchema = joi.object().keys({
limit: joi.number().integer().default(20).min(1).max(1000),
offset: joi.number().integer().default(0).min(0),
"association": joi.string().valid(Object.keys(model.associations).map(modelName => getFixedModelName(modelName))).required(),
// "attributes": joi.array().items(incAttrWhen),
attributes: joi.alternatives(
joi.object().keys({
exclude: joi.array().items(
incAttrWhen
).required()
}),
joi.array().items(
incAttrWhen
)
),
'where': incWhereWhen,
'required': joi.boolean()
});
}
return joi.object().keys({
attributes: joi.alternatives(
joi.object().keys({
exclude: joi.array().items(
joi.string().valid(Object.keys(model.rawAttributes)).required()
).required()
}),
joi.array().items(
joi.string().valid(Object.keys(model.rawAttributes)).required()
)
),
include: modelAssociations.length ? joi.array().items(incSchema) : joi.any().forbidden(),
where: joi.object().keys(whereAttrs),
limit: joi.number().integer().default(20).min(1).max(1000),
offset: joi.number().integer().default(0).min(0),
order: joi.array().items(joi.array())
});
};
// defining model level filter and validations based on joi
const User = sequelize.define('User', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
joiFilter: joi.object().keys({
"$eq": joi.number(),
"$between": joi.array().items(joi.string().min(1)).max(2)
}).xor("$eq", "$between")
},
nationalCode: {
type: DataTypes.STRING,
joiFilter: joi.object().keys({
"$eq": joi.string().length(10),
"$like": joi.array().items(joi.string().min(1)).max(2)
}).xor("$eq", "$like")
},
...
});
// usage ex: model name is "User" in this case
const filter = {attributes:[...],where:{...},include:[{associaiton:"",...}],..}
const validate = getModelValidationSchema("User").validate(filter);
if(validate.error) {
//error
}else{
// validation ok
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment