Skip to content

Instantly share code, notes, and snippets.

@foyzulkarim
Created March 3, 2024 12:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save foyzulkarim/bd342263f2af5ce74df90d6540cd59f0 to your computer and use it in GitHub Desktop.
Save foyzulkarim/bd342263f2af5ce74df90d6540cd59f0 to your computer and use it in GitHub Desktop.
Simplify Express.js Validation: Sync Joi and Mongoose Schemas
const viewModelProps = {
title: { type: String, isRequired: true, minLength: 5, unique: true, index: true },
category: { type: String, isRequired: true },
}
// in mongoose
const videoSchema = new mongoose.Schema({
...generateSchema(true, viewModelProps),
duration: {
type: Number,
min: 0,
}});
const Video = mongoose.model('Video', videoSchema);
// in joi
const schema = Joi.object().keys({
_id: Joi.string().optional(),
...generateSchema(false, viewModelProps),
});
const isJoiString = (options = {}) => {
const { minLength = 1, maxLength = 50, required = true } = options;
let schemaProp = Joi.string().min(minLength).max(maxLength);
if (required) {
schemaProp = schemaProp.required();
}
return schemaProp;
};
const isMongoString = (options = {}) => {
const {
minLength = 1,
maxLength = 100,
required = true,
trim = true,
...otherOptions
} = options;
return {
type: String,
required,
trim,
minLength,
maxLength,
...otherOptions,
};
};
const isString = (isDbSchema, options = {}) => {
if (isDbSchema) {
return isMongoString(options);
} else {
return isJoiString(options);
}
};
const generateSchema = (isDb, props) => {
Object.keys(props).forEach((key) => {
const propertyOptions = props[key];
if (propertyOptions.type.name === 'String') {
schema[key] = isString(isDb, propertyOptions);
} else {
// Handle unsupported types - you might want to throw an error here
throw new Error(`Unsupported type: ${propertyOptions.type}`);
}
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment