Narnia's Psychedelic Mushrooms

    @mangroves/jamcaa-helper
    TypeScript icon, indicating that this package has built-in type declarations

    0.2.0 • Public • Published

    jamcaa-helper (饮茶小助手)

    codecov Node.js CI

    If you are using:

    • Nestjs
    • TypeORM
    • MySQL

    Then you can drink a cup of tea instead of spending time on writing CRUD code.

    Installation

    yarn add @mangroves/jamcaa-helper

    Usage

    Instantiation

    import { JamcaaHelper } from '@mangroves/jamcaa-helper'
    import { InjectRepository } from '@nestjs/typeorm'
    import { Entity } from './entity.ts'
    
    @Injectable()
    export class SomeService {
      private readonly crudHelper = new JamcaaHelper(SomeEntity, 'entityUniqueKey' /** , options, connectionName */)
    
      constructor (
        // You may need to inject repository if you get a `RepositoryNotFoundError`
        @InjectRepository(Entity)
        private readonly repository: Repository<Entity>,
      ) {}
    }

    Create

    Feature

    What does this method do?

    1. Check if record already exists according to unique keys
    2. Reuse soft deleted record according to options
    3. Increase data_version
    4. Add creator and updater to entity
    5. Add create_time and update_time
    6. Save to database and return saved entity

    Exceptions

    • Throw 400 if entity already exists

    Example

    import { JamcaaHelper } from '@mangroves/jamcaa-helper'
    
    @Injectable()
    export class SomeService {
      private readonly crudHelper = new JamcaaHelper(SomeEntity, 'entityUniqueKey' /** , options, connectionName */)
    
      async create (dto: DTO, operator: string) {
        const partialEntity = getEntityFromDTO(dto)
        const savedEntity = await this.crudHelper.createInsertQuery(partialEntity, operator)
        return getDTOFromEntity(savedEntity)
      }
    }

    List

    Feature

    1. Create and return a ListQuery instance (an internal class)
    2. You don't need to care about null/undefined/empty/array filter value in DTO
    3. Dealing with soft delete according to options

    Exceptions

    None

    Example

    import { JamcaaHelper } from '@mangroves/jamcaa-helper'
    
    @Injectable()
    export class SomeService {
      private readonly crudHelper = new JamcaaHelper(SomeEntity, 'entityUniqueKey' /** , options, connectionName */)
    
      async list (dto: DTO) {
        const [entities, totalSize] = await this.crudHelper.createListQuery()
          .filter((filterQuery) => {
            filterQuery
              .equals('column1', dto.column1)
              .equals('column2', dto.column2)
          })
          .showDeletedQuery()
          .paginationQuery(dto.page_number, dto.page_size)
          .getQueryBuilder()
          .getManyAndCount()
        return {
          entities,
          total_size: totalSize
        }
      }
    }

    Get

    Feature

    1. Dealing with soft delete according to options

    Exceptions

    • Throw 404 if entity not found

    Example

    import { JamcaaHelper } from '@mangroves/jamcaa-helper'
    
    @Injectable()
    export class SomeService {
      private readonly crudHelper = new JamcaaHelper(SomeEntity, 'entityUniqueKey' /** , options, connectionName */)
    
      async get (id: string) {
        const uniqueKeyConditions = { id }
        const entity = await this.crudHelper.createGetQuery(uniqueKeyConditions)
        return getDTOFromEntity(entity)
      }
    }

    Update

    Feature

    1. Update record using FieldMask
    2. Update data_version
    3. Update updater
    4. Update update_time

    Exceptions

    • Throw 404 if entity not found
    • Throw 400 if update_mask contains disallowed fields
    • Throw 400 if nothing updated

    Example

    Note: If you want to validate data_version, you must transform it in transformToEntity.

    import { JamcaaHelper } from '@mangroves/jamcaa-helper'
    
    @Injectable()
    export class SomeService {
      private readonly crudHelper = new JamcaaHelper(SomeEntity, 'entityUniqueKey' /** , options, connectionName */)
    
      async update (id: string, dto: DTO, operator: string) {
        const uniqueKeyConditions = { id }
        const dto = { first_name: 'Charlie', person_info: { age: 12 }, data_version: '1' }
        const updateMask = ['first_name', 'person_info.age']
        const allowedMask = ['first_name', 'person_info']
        const transformFromEntity = (entity) => ({
          first_name: entity.firstName,
          person_info: entity.personInfo,
        })
        const transformToEntity = (dto) => ({
          firstName: dto.first_name,
          personInfo: dto.person_info,
          // Transform data_version if you want to validate it.
          dataVersion: dto.data_version,
        })
        const updatedEntity = await this.crudHelper.createUpdateQuery(
          uniqueKeyConditions,
          dto,
          updateMask,
          allowedMask,
          operator,
          transformFromEntity,
          transformToEntity,
        )
        return getDTOFromEntity(updatedEntity)
      }
    }

    Delete

    Feature

    1. Dealing with soft delete according to options
    2. Add updater if soft delete feature enabled

    Exceptions

    • Throw 404 if entity not found

    Example

    import { JamcaaHelper } from '@mangroves/jamcaa-helper'
    
    @Injectable()
    export class SomeService {
      private readonly crudHelper = new JamcaaHelper(SomeEntity, 'entityUniqueKey' /** , options, connectionName */)
    
      async delete (id: string, operator: string) {
        const uniqueKeyConditions = { id }
        await this.crudHelper.createDeleteQuery(uniqueKeyConditions, operator)
      }
    }

    Constructor Options

    Option Type Default Description
    maxUnspecifiedPageSize number 100 Max page size if it is not specified
    softDelete boolean true Whether soft delete feature should be applied
    softDeleteField string 'deleteStatus' Soft delete column field
    softDeleteEnum [undeleted: any, deleted: any] [0, 1] The values to mark if record is deleted
    reuseSoftDeletedData boolean true Whether to reuse soft deleted data
    dataVersion boolean true Whether to increase data version column on update
    dataVersionField string 'dataVersion' Data version column field
    dataVersionType 'string' or 'number' 'string' Data version type
    validateDataVersion boolean true Whether to validate data_version or not
    hasOperator boolean true Whether there are creator and updater columns
    creatorField string 'creator' Creator column field
    updaterField string 'updater' updater column field
    hasTime boolean true Whether there are create_time and update_time columns
    createTimeField string 'createTime' Create time column field
    updateTimeField string 'updateTime' Update time column field
    timePrecision 'ms' or 's' 'ms' Store time column with the precision to millisecond or second
    onEntityAlreadyExistsError (entityName: string) => never Throw 400 exception To throw an exception when entity already exists
    onEntityNotFoundError (entityName: string) => never Throw 404 exception To throw an exception when entity not found
    onDisallowedUpdateMaskError (disallowedMask: string[]) => never Throw 400 exception To throw an exception when update_mask contains disallowed fields
    onDataVersionError () => never Throw 400 exception To throw an exception when data_version is not equal to the existing entity's
    onNothingUpdatedError () => never Throw 400 exception To throw an exception when nothing updated

    Test

    unit

    yarn test:unit

    e2e

    Real MySQL environment required.

    We run e2e test with real database running on Docker.

    1. Install Docker
    2. Execute the following command to start a MySQL container
    yarn db

    Then execute

    yarn test:e2e

    After test run, use the following command to stop and remove MySQL container (Optional)

    yarn db:destroy

    Caveat

    Make sure you are using the same TypeORM library in node_modules, or else JamcaaHelper will not get the correct ORM connection.

    Install

    npm i @mangroves/jamcaa-helper

    DownloadsWeekly Downloads

    0

    Version

    0.2.0

    License

    MIT

    Unpacked Size

    54.2 kB

    Total Files

    7

    Last publish

    Collaborators

    • chuchencheng