mc-helpers
TypeScript icon, indicating that this package has built-in type declarations

1.3.5 • Public • Published

Installation

Install mc-helpers package. -E will install the exact version

//with npm
npm i mc-helpers -E

To get started with mc-helpers is necesary to configure mongoose models and Services.

Services

  • This is the basic service configuration
//services/store.ts
import { BaseServices } from "mc-helpers";
import { StoreModel, StoreProps } from "../models/Store";

export const StoreService = new BaseServices<StoreProps>(StoreModel)
  • In order to override the New, Edit, Find methods, you will need to override some methods. ApiError explication is below
//services/store.ts
import {ApiError, BaseServices} from 'mc-helpers'
import {StoreErrors} from '../errors/Store.errors'
import {StoreModel, StoreProps} from '../models/Store'

interface NewProps {
  name: string
}

class Service extends BaseServices<StoreProps> {
  constructor() {
    super(StoreModel)
  }

  New = async (props: NewProps) => {
    const {name} = props
    const check = await this.Exists({nombre: {$regex: new RegExp(name, 'i')}})
    if (check) throw new ApiError(StoreErrors.Exists)

    return await this.Create(props)
  }

  Find = (extraParams: any) => {
    return this.Model.aggregate().sort({name:-1})
  }
}

export const StoreService = new Service()
  • You can override multiple methods from the BaseService class. New, Edit, Find, Paginate, Export, PrePaginate, Filter, etc.
export class BaseServices<T, K = any> {
  Model: FinalModel<T>
  constructor(model: FinalModel<T>) {
    this.Model = model
  }

  Create: CreateProps<T, K> = async (item) => {
    const created = await this.Model.create(item)
    return this.FindById(created.id)
  }

  Exists: ExistsProps<T> = async (find) => {
    return this.Model.findOne(find)
  }

  New: BaseNewProps<K> = async (item: any) => {
    return this.Create(item)
  }

  CheckCreate: CheckCreateProps<T, K> = async (find, item) => {
    const check = await this.Exists(find)
    if (!check) {
      return this.Create(item || (find as T))
    }

    return this.FindById(check.id)
  }

  Modify: ModifyProps<T> = async (_id, item) => {
    return await this.Model.findByIdAndUpdate(_id, item)
  }

  Edit: EditProps<T, K> = async (_id, item) => {
    const edited = await this.Modify(_id, item)
    return this.FindById(edited?.id)
  }

  Delete: DeleteProps<T> = async (_id) => {
    return this.Model.findByIdAndDelete(_id)
  }

  DeleteAll: DeleteAllProps = () => {
    if (process.env.NODE_ENV !== 'test')
      throw Error('No se puede utilizar fuera del entodo de test')

    return this.Model.deleteMany({})
  }

  DocById: DocByIdProps<T> = async (id) => {
    const document = await this.Model.findById(id)
    return document
  }

  FindById: FindByIdProps<K> = async (id) => {
    const aggregate = this.Find().match({_id: Types.ObjectId(id)})
    const [full] = await aggregate
    return full
  }

  Find: BaseFindProps<K> = () => {
    const aggrete = this.Model.aggregate()
    return aggrete.sort({createdAt: -1})
  }

  Filter: FiltersProps = (filters) => {
    return prepareFilter(filters)
  }

  PrePaginate: PrePaginateProps<K> = (aggregate) => aggregate

  Paginate: PaginateProps = async (pageConfig, extraParams) => {
    const {page, filters, limit, sort} = pageConfig

    const finalFilters = this.Filter(filters)
    const aggregate = this.Find(extraParams).match(finalFilters)
    const finalSort = prepareSort(sort)
    if (sort) aggregate.sort(finalSort)

    const finalAggregate = this.PrePaginate(aggregate, pageConfig, extraParams)
    return this.Model.aggregatePaginate(finalAggregate, {page, limit: limit || 10})
  }

  Export: ExportProps = async () => {
    throw new ApiError(NoExportOverride)
  }

  Base: BaseProps<T> = () => this.Model
}

Models

//models/store.ts
import {createModel, createSchema, FinalDoc} from 'mc-helpers'

export type StoreProps = {name: string}

const schema = createSchema<StoreProps>({name: String})
export const StoreModel = createModel<StoreProps>('store', schema)
export type StoreDocument = FinalDoc<StoreProps>

ROUTES

For each service you will to configure an use from express route, yo can set arrays middlewares for every created route, getId, post, get, put, delete, export the same for errors which must be ValidationChain[]

//routes/api.ts
const storeRoute = configureRoute({
  api: StoreService,
  middlewares: {
    getId: [authentication],
    post: [authentication],
  },
  errors: {post: [StoreErrors.NoName]},
})
router.use('/store', storeRoute)

Error Handlers

  • In order to throw ApiError is necesary to configure the Errors per Route/Api. You can created as follow ValidationChain its from express.validator must be set in the route configuration ErrorMessage can be throw by ApiError basicaly generates an Object {name:string, code:number}

addCheck adds check for get params addBody adds checks for put/post/delete params

import {ValidationChain} from 'express-validator'
import {ErrorMessage, Errors} from 'mc-helpers'

interface ErrorResponse {
  NoPage: ValidationChain
  NoName: ValidationChain
  Exists: ErrorMessage
}

export const StoreErrors = Errors.generateError<ErrorResponse>(400, { // Error code number 400 401 402
  NoPage: Errors.addCheck('page'),
  NoName: Errors.addBody('name'),
  Exists: Errors.addMessage('The store already existis'),
})

Helpers

  • Configure ENV vars. require dontenv. Create a file .env in root dir with the env vars required.
type ENV_TYPE = 'development' | 'production' | 'test'
type EnvProps = {PORT: number; NAME: string; NODE_ENV: ENV_TYPE}

const proccesEnv = configureEnv<EnvProps>('PORT', 'NAME', 'NODE_ENV')

Last

  • Do not forget to configure mongo!
const dbFinalName = `DBNAME`
const finalConnString = `${Config.MONGODB}${dbFinalName}`
mongoose.connect(finalConnString, {
  useUnifiedTopology: true,
  useNewUrlParser: true,
  useCreateIndex: true,
  useFindAndModify: false,
})

mongoose.connection.on('connected', () => {
  console.log(`Conectado a ${finalConnString}`)
})

Readme

Keywords

none

Package Sidebar

Install

npm i mc-helpers

Weekly Downloads

8

Version

1.3.5

License

ISC

Unpacked Size

6.24 MB

Total Files

16

Last publish

Collaborators

  • julianlionti