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

fundering

v2.2.0

Published

<p align='center'> A pragmatic service framework for structured and reactive data handling using <a href='https://github.com/Automattic/mongoose' target='_blank'>Mongoose</a>. </p>

Downloads

104

Readme

Description

Fundering acts as a ground layer of your service architecture and helps you keep your application structured by offering helper methods and reactive hooks. Rather than reinventing the wheel, the framework uses Mongoose ORM for communication with MongoDB and extends upon the functionality that is already there. A few examples of these functionalities are; dynamic population, recursive authorization, query type casting and service based document middleware.

Installation

$ npm install fundering mongoose

Getting started

Initializing a service is as easy as extending the abstract CrudService class and passing your schema model in the constructor. This class registers your service with fundering for cross-service authorization and casting, and offers a set of methods which help you with basic CRUD actions.

import { CrudService } from 'fundering';
import { IUser } from './user.interface';
import { model } from 'mongoose';
import { userSchema } from './user.schema';

export class UsersService extends CrudService<IUser> {
  constructor() {
    super(model('User', userSchema));
  }
}

Examples

Querying

MongoDB aggregations are great, powerful and fast, but they can also be complex, hard to maintain and (really) slow. The find methods in the CrudService help you keep the positive set of adjectives by utilizing common aggregations for you. The features vary from adding referenced documents to your conditions to randomly sorting the collection before selecting results. The IQueryOptions object also allows you to extend existing methods with extra query conditions for a more dynamic codebase.

class UsersService extends CrudService<IUser> {
  constructor() {
    super(model('User', userSchema));
  }

  getPopulatedGroups() {
    // get all users with their group fields populated
    return this.find({}, { populate: ['group'] });
  }

  getByGroupName(name: string) {
    // find users based on the name of their referenced group
    // sort the users on the createdAt date of their group descending
    return this.find({ 'group.name': name }, { sort: ['-group.createdAt'] });
  }

  getFiveUniqueNames(options?: IQueryOptions) {
    // find 5 randomly sorted unique first names while supporting extending the query
    return this.find({}, { ...options, distinct: 'firstName', random: true, limit: 5 });
  }
}

Authorization

Authorization plays a huge part in most production applications and implementing it properly can come at the cost of readability and/or performance. You can implement the IOnAuthorization interface to utilize the onAuthorization() method in your CrudService. This method is triggered on every find query called through the CrudService and allows you to return a MongoDB expression object to which the returned documents must comply.

Note: you can imbue the options object with user data to create rules based on context. This is elaborated upon in the wiki.

class UsersService extends CrudService<IUser> implements IOnAuthorization {
  constructor() {
    super(model('User', userSchema));
  }

  async onAuthorization(options: IAuthOptions): Promise<Expression> {
    // limit the user's access to just his/her own account
    return { $eq: ['$_id', options.user?._id] };
  }
}

Document middleware

Fundering offers opt-ins for document middleware through service methods. By moving these methods to the service level you are able to keep your logic more centralized and make use of patterns like dependency injection more easily. Fundering also extends the functionality by allowing context injection and keeping all arguments neatly typed.

class UsersService extends CrudService<IUser> implements IPreSave {
  constructor() {
    super(model('User', userSchema));
  }

  async preSave(payload: IUserModel, options?: IQueryOptions<IUser>) {
    // encrypt modified passwords
    if(payload.isModified('password')) {
        payload.password = encrypt(payload.password)
    }
  }
}

Documentation

You can consult the wiki for more detailed information about the following subjects:

Using Fundering with Nestjs?

Make sure you check out the nest-utilities package for flexible endpoints and a great developer experience for front-enders and back-enders alike.


Made by Martin Drost - Buy me a ☕