npm package: @jinyexin/core
Description: A scalable RESTAPI framework build with the idea of KISS(keep it simple, stupid): With [@jinyexin/corecli](https://www.npmjs.com/package/@jinyexin/corecli) you can generate following code from database in seconds.
Author: Enix Jin
Latest version: 3.3.10

# core

A scalable RESTAPI framework build with the idea of KISS(keep it simple, stupid):
With [@jinyexin/corecli](https://www.npmjs.com/package/@jinyexin/corecli) you can generate following code from database in seconds.

* RESTAPI: Typescript + express + swagger (Support Mysql and PostgreSQL)

* Frontend: Angular7+ CoreUI
    
[source code](https://gitlab.com/jinyexin/core)
    
## changelog

See [CHANGELOG](https://gitlab.com/jinyexin/core/blob/master/CHANGELOG.md) 
    
## Prerequisites:

   * NodeJS >= 8.12
   
   * npm i -g @jinyexin/corecli

## Generate from database


See [@jinyexin/corecli](https://www.npmjs.com/package/@jinyexin/corecli)

## web


    cd web
    
    git init

    npm i
   
    npm start


##domain


    cd domain
    
    git init

    npm i

    npm start

##Example code

    //app.ts
    let application = new App(
        {
            appName: "domain",
            controllers: [
                userController,
                ...//all your controller register here
                userDeviceController,
                // optional image upload
                imageController
            ],
            // uncomment following code to enable socket.io
            // gateway: Gateway,
            
            // initialDatabase: true,
            // enableSwagger: true
        }
    );
    
    application.init();
    
    
    //userController.ts
    //@CRUDController(User,false) to disable auth check for all method under this controller
    @CRUDController(User)
    export class userController {
    
        @Inject()
        repository: userRepository;
        
        @Post({url: '/login', auth: false})
        async login(req, res, next): Promise<any> {
            if (req.body && req.body.username && req.body.password) {
                logger.info("login user:" + req.body.username);
                let result = await serviceFactoryImpl.getInstance().getAuthenticationService().login(req.body.username, req.body.password, this.repository)
                if (result) {
                    return result;
                } else {
                    throw defaultException.WARNING_authFail;//build in exception
                }
            } else {
                throw new serviceException("user or password missing", 400);//customize exception
            }
        }

        @Get({
                url: '/test/:id',
                callbacks: [async (req, res, next) => {
                    let user = await encryption.getAuthentication(req);
                    //check if user is admin, you should extract this check to a method for reuse
                    if (user.role != 1) {
                        throw new serviceException("only admin could access this api", 403);
                    }
                    next();
                }]
            })
        async test(req,res,next){
            let result = await this.repository.test(req.params.id);
            return result;
        }
        
        @Post({url: "/pagedsql", auth: false})
        async pagedtest(req, res) {
            return this.repository.pagedTest(req.body as PageInfo);
        }
    }


    //userRepository.ts
    @Repository()
    export class userRepository extends baseUserRepository<User> {

        constructor() {
            super(User);
        }

        @SQL("select * from xxx_user where id = ?")
        test(id) {
        }
        
        @PagedSQL("select xxx_user.id as user_id,xxx_user.username,xxx_device.device_id from xxx_user join xxx_device on xxx_user.id = xxx_device.admin_id")
        pagedTest(pageInfo: PageInfo) {
        }

    }
    
    
    //imageController.ts
    @FileUploadController({
        baseUrl: "/image",
        uploadFolder: global.config.imagePath,
        nameSingle: "image",
        nameMulti: "images"
    })
    export class imageController {
    
    }
    
    //Gateway.ts
    @WebSocketGateway()
    export class Gateway {
    
        @Inject()
        deviceService: deviceService;
    
        @SendMessage({interval: 5000, event: "device data"})
        async deviceData() {
            return await this.deviceService.getData();
        }
        
        @SubscribeMessage({event: "test"})
        async test(io: SocketIO.Server, socket: SocketIO.Socket, data: any) {
            //do anything with io and current socket
            logger.warn("get test message:", JSON.stringify(data));
        }
    
    }