tsg-mongoose
v1.1.3
Published
Auto create api by schema
Downloads
4
Maintainers
Readme
tsg
This is Typescript with Express API,model generator from Mongoose Schema model.
Description
Create Schema file, use command line interface to auto generate API, model file with referance.
Usage
// create api and with baseSchema file
tsgm g 'file url'
// create api with baseSchema file
tsgm a 'file url'
tsgm api 'file url'
// create model with baseSchema file
tsgm m 'file url'
tsgm model 'file url'
// create base schemaModel
tsgm m --base=course
Result
BaseSchema Exmaple
import { Schema, model, Document } from 'mongoose';
const schema = new Schema({
title: { type: String, required: true },
uniqueName: { type: String, unique: true, required: true },
content: { type: String, required: true },
img: { type: Schema.Types.ObjectId, ref: 'File' },
photo: { type: Schema.Types.ObjectId, ref: 'File' },
type: { type: Schema.Types.ObjectId, ref: 'CourseType', required: true },
students: [{ type: Schema.Types.ObjectId, ref: 'User' }],
}, { timestamps: true });
export const CourseSchema = model('Course', schema);
Install
npm install tsg-mongoose -g
Config
// create api with noSearch Query
tsgm api 'file url' noQuery method
// create api with method by order,
// if no method, default is 'get,getid,use,post,patch,delete'
tsgm api 'file url' method=get,getid,use,post,patch,delete
Result
generate file like below
API
import { Router } from 'express';
import { Request, Response, NextFunction } from 'express';
import { loginCheck } from '../libs/login-check';
import { query, validationResult, body } from 'express-validator/check';
import { myLib } from '../libs/plugin';
import { getValidationData } from '../libs/getValidationData';
import { UserSchema } from '../models/user.model';
import { CourseModel, CourseSchema } from '../models/course.model';
import { FileModel, FileSchema } from '../models/file.model';
import { CourseTypeModel, CourseTypeSchema } from '../models/coursetype.model';
const dbHandler = async (req: Request) => {
const updater = await UserSchema.getTokenUser(req.headers.authorization);
const img = await FileSchema.findById(req.body.img) as FileModel;
const photo = await FileSchema.findById(req.body.photo) as FileModel;
const type = await CourseTypeSchema.findByIdRequired(req.body.type) as CourseTypeModel;
return {
updater: updater,
img: img,
photo: photo,
type: type,
};
};
export const courseApi = Router()
.get('/', [
query('title'),
query('uniqueName'),
query('content'),
query('img'),
query('photo'),
query('type'),
query('students'),
query('student2s'),
], async (req: Request, res: Response, next: NextFunction) => {
try {
const courses = await CourseSchema.find(myLib.querySearch(req, []))
.populate('img', [])
.populate('photo', [])
.populate('type', [])
.populate('creator', ['email', 'firstName', 'lastName'])
.populate('updater', ['email', 'firstName', 'lastName'])
.sort({ 'sort': 1 });
return res.success({
message: 'Success',
obj: courses
});
} catch (err) {
return next(err);
}
})
.get('/:id', async (req: Request, res: Response, next: NextFunction) => {
try {
const course = await CourseSchema.findById(req.params.id)
.populate('img', [])
.populate('photo', [])
.populate('type', [])
.populate('creator', ['email', 'firstName', 'lastName'])
.populate('updater', ['email', 'firstName', 'lastName'])
.sort({ 'sort': 1 });
return res.success({
message: 'Success',
obj: course
});
} catch (err) {
return next(err);
}
})
.use('/', loginCheck)
.post('/', [
body('title', 'Invalid title').exists(),
body('uniqueName', 'Invalid uniqueName').exists(),
body('content', 'Invalid content').exists(),
body('img', 'Invalid img'),
body('photo', 'Invalid photo'),
body('type', 'Invalid type').exists(),
body('students', 'Invalid students'),
body('student2s', 'Invalid student2s'),
body('sort', 'Invalid type').toInt().optional({ checkFalsy: true }),
body('enable', 'Invalid type').toBoolean().optional({ checkFalsy: true }),
], async (req: Request, res: Response, next: NextFunction) => {
try {
const bodyData = await getValidationData(req);
const dbData = await dbHandler(req);
const course = <CourseModel>(await new CourseSchema({
...bodyData,
...dbData,
creator: dbData.updater,
}).save());
if (dbData.img) {
course.img = await dbData.img
.moveAndUpdate(dbData.updater, `${CourseSchema.collection.name}/${course._id}`);
}
if (dbData.photo) {
course.photo = await dbData.photo
.moveAndUpdate(dbData.updater, `${CourseSchema.collection.name}/${course._id}`);
}
return res.success({
status: 201,
message: 'Success',
obj: course
});
} catch (err) {
return next(err);
}
})
.patch('/:id', [
body('title', 'Invalid title').exists(),
body('uniqueName', 'Invalid uniqueName').exists(),
body('content', 'Invalid content').exists(),
body('img', 'Invalid img'),
body('photo', 'Invalid photo'),
body('type', 'Invalid type').exists(),
body('students', 'Invalid students'),
body('student2s', 'Invalid student2s'),
body('sort', 'Invalid type').toInt().optional({ checkFalsy: true }),
body('enable', 'Invalid type').toBoolean().optional({ checkFalsy: true }),
], async (req: Request, res: Response, next: NextFunction) => {
try {
const bodyData = await getValidationData(req);
const dbData = await dbHandler(req);
let course: CourseModel = <CourseModel>(await CourseSchema
.findByIdAndUpdate(req.params.id, {
$set: {
...bodyData,
...dbData
}
}));
if (course.type !== dbData.type) {
await CourseTypeSchema.findByIdAndUpdate(course.type, { '$pull': { 'courses': course._id } });
await dbData.type.update({ '$push': { 'courses': course._id } });
}
if (dbData.img) {
await (dbData.img as FileModel).moveAndUpdate(dbData.updater, `${CourseSchema.collection.name}/${course._id}`);
}
if (!dbData.img || dbData.img._id !== course.img) {
await FileSchema.findByIdAndRemove(course.img);
}
if (dbData.photo) {
await (dbData.photo as FileModel).moveAndUpdate(dbData.updater, `${CourseSchema.collection.name}/${course._id}`);
}
if (!dbData.photo || dbData.photo._id !== course.photo) {
await FileSchema.findByIdAndRemove(course.photo);
}
course = <CourseModel>await CourseSchema
.findById(req.params.id)
.populate('img', [])
.populate('photo', [])
.populate('type', [])
.populate('creator', ['email', 'firstName', 'lastName'])
.populate('updater', ['email', 'firstName', 'lastName'])
.sort({ 'sort': 1 });
return res.success({
message: 'Success',
obj: course
});
} catch (err) {
return next(err);
}
})
.delete('/:id', async (req: Request, res: Response, next: NextFunction) => {
try {
const course = await CourseSchema.findByIdAndRemove(req.params.id);
return res.success({
message: 'Success',
obj: course
});
} catch (err) {
return next(err);
}
});
model
import { Schema, model, Document, Model } from 'mongoose';
import { BaseModel, BaseSchema } from '../libs/base.model';
import { myLib } from '../libs/plugin';
import { removePlugin } from '../libs/mongoose/remove.plugin';
import { environment } from '../environments/environment';
import * as path from 'path';
import { FileModel, FileSchema } from './file.model';
import { CourseTypeModel } from '../models/coursetype.model';
import { UserModel } from '../models/user.model';
export interface CourseModel extends Document, BaseModel {
title: string;
uniqueName: string;
content: string;
img?: FileModel;
photo?: FileModel;
type: CourseTypeModel;
students?: UserModel[];
student2s?: UserModel[];
}
const schema = new Schema({
...BaseSchema,
title: { type: String, required: true },
uniqueName: { type: String, required: true, unique: true },
content: { type: String, required: true },
img: { type: Schema.Types.ObjectId, ref: 'File' },
photo: { type: Schema.Types.ObjectId, ref: 'File' },
type: { type: Schema.Types.ObjectId, ref: 'CourseType', required: true },
students: [{ type: Schema.Types.ObjectId, ref: 'User' }],
student2s: [{ type: Schema.Types.ObjectId, ref: 'User' }],
}, { timestamps: true })
.plugin(removePlugin, async (course: CourseModel) => {
try {
if (course) {
await FileSchema.findByIdAndRemove(course.img);
await FileSchema.findByIdAndRemove(course.photo);
myLib.deleteDir(path.join(environment.uploadUrl,
this.CourseSchema.collection.name, course._id.toString()));
}
} catch (err) {
console.log(err);
}
})
.post('save', async (course: CourseModel) => {
try {
const result = await course.type.update({ '$push': { 'courses': course._id } });
} catch (err) {
console.log(err);
}
});
schema.statics.findByIdRequired = async function (id: string) {
try {
if (!id) throw null;
return await this.model('Course').findById(id);
} catch (err) {
throw (<ResponseObj>{
message: 'error course type',
});
}
};
export const CourseSchema = model('Course', schema) as Model<Document> & {
findByIdRequired: (id: string) => CourseModel
};