npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mc-helpers

v1.3.5

Published

Configure Backend to use material-crud

Downloads

36

Readme

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}`)
})