Created
March 13, 2018 19:49
-
-
Save alisherafat01/a16a3612545e206cba3ede4125b31931 to your computer and use it in GitHub Desktop.
sequelize-joi validation helper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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