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

alpacas

v0.0.7

Published

Single-source-of-truth for Express / Mongodb APIs

Downloads

10

Readme

Alpacas!

A single-source-of-truth for Express / Mongodb APIs, with auto-generated documentation, routes,mongoose models, type casting and validation and more.

Getting Started

Prerequisites

This assumes you have nodejs and a mongodb instance available.

Installing

Add alpacas as a depency of your project, along with express and mongoose.

npm install --save alpacas express mongoose

Add some boilerplate code

// index.js

const express = require( "express" );
const mongoose = require( "mongoose" );
const { AlpacaModel, AlpacaTypes, AlpacaValidators }  = require( "./lib/index" );

const mongoURI = process.env.MONGO_URI || "mongodb://localhost/alpacas";
mongoose.connect( mongoURI );
const app = express();

app.use( express.json( { limit: "5mb" } ) );
app.use( express.urlencoded( { extended: false } ) );


const { AlpacaString, AlpacaDate, AlpacaInt, AlpacaArray, AlpacaReference } = AlpacaTypes;
const options = {
  timestamps: true,
  generateTs: {
    dir: path.join( __dirname, ".", "docs", "ts" ),
  },
  generateOpenApi: {
    dir: path.join( __dirname, ".", "docs", "ts" ),
  }
}

const name = new AlpacaString( { 
  validate: (name) => name && name.length < 20 
} )

const email = new AlpacaString( { 
  validate: AlpacaValidators.isValidEmail 
} )
const ref = new AlpacaReference();
const options = {
  timestamps: true,
  generateTs: {
    dir: path.join( __dirname, ".", "docs", "ts" ),
  },
  generateOpenApi: {
    dir: path.join( __dirname, ".", "docs", "ts" ),
  },
}
const company = new AlpacaModel("Company", {
  name: name,
}, {
  ...options,
  nestedRest: [{path:"users",foreignField:"company",modelName:"User"}]
})

const user = new AlpacaModel("User", {
  first_name: name,
  last_name: name,
  email: {
    type: email,
    required: true,
    description: "email address",
    example: "[email protected]",
  },
  company: {
    type: new AlpacaArray( ref ),
    ref: "Company",
    populate: true,
  }
}, options )


app.use( "/api/company", company.router );
app.use( "/api/user", user.router );

app.use( ( req, res ) => {
  res.json( res.locals );
} );

app.use( ( err, req, res, next ) => {
  res.json( {
    error: err.message,
    trace: err.stack,
  } );
} );

app.listen( 3000 );

When you start the app, you'll get working crud routes at /api/user and /api/company. The following table shows the default routes for an example model:

| Route name | URL | HTTP Verb | | ----------- | --- | ---------- | | Create | /api/model | POST | | Index | /api/model | GET | | Read | /api/model/:id | GET | | Update | /api/model/:id | POST | | Delete | /api/model/:id | DELETE |

Configuration

There are three main exports from Alpacas. The AlpacaModel, AlpacaTypes, and AlpacaValidators.

AlpacaValidators

AlpacaValidators are a set of validation functions for a range of different scenarios.

AlpacaTypes

AlpacaTypes are a bunch of different classes which inherit from the base AlpacaType, such as AlpacaString, or AlpacaInt. The constructor takes an object with two main properties: "validate" and "cast" which are both functions or arrays of functions.

Validation functions take any type and return a boolean indicating if the input passed validation.

Cast functions take any type and transform it, passing it to the next cast function.

Types also have a primitive, which can be overwritten by setting the "primitive" property in the object passed to the constructor. Any valid type for a Mongoose model field will work.

type AlapacaPrimitive = StringConstructor | NumberConstructor | DateConstructor | typeof Schema.Types.ObjectId;
type AlpacaValidator = ((value: any) => boolean);
type AlpacaCaster = ((value: any) => any)
interface AlpacaTypeOptions {
  primitive?: AlapacaPrimitive
  null_or_non_empty_trimmed_string?: boolean
  validate?: AlpacaValidator | AlpacaValidator[]
  cast?: AlpacaCaster | AlpacaCaster[]
}

AlpacaModel

AlpacaModels are the main workhorse of the library. The constructor functions take 3 inputs, the model name, the schema, and an optional object of AlpacaModelOptions.

interface AlpacaSchema {
  [key: string]: AlpacaModelProp,
}

interface AlpacaModelProp {
  type: AlpacaType | AlpacaArray
  ref?: string
  populate?: boolean
  required?: boolean
  readOnly?: boolean
  example?: any
  description?: string
  enum?: any[]
}

interface AlpacaModelTSOptions {
  dir: string
  filePath?: string
  additionalProperties?: boolean
}

interface AlpacaModelOpenAPIOptions {
  dir: string
  filePath?: string
  tags?: string[]
}

interface AlpacaNestedRestOptions {
  path: string
  foreignField: string
  modelName: string
}

interface AlpacaModelOptions {
  manualInit?: boolean;
  generateTs?: AlpacaModelTSOptions;
  generateOpenApi?: AlpacaModelOpenAPIOptions;
  nestedRest?:AlpacaNestedRestOptions[];
  timestamps?: boolean;
  schemaCallback?: (( Schema: Schema ) => void )
}

The key properties on the AlpacaModel are router, which is an Express router with the default crud routes; and model, which is the mongoose model instance. Other important ones are cast and validate, which act similarly to the methods on the AlpacaType. Other important properties are the crud middleware methods read, index, create, update, destroy and getAlpacaMountMiddleware().

You can add a nested http method using the following method pushNestedRoute( method:nestedRouteAllowedMethods, path:string, middleware:middleware )

The mongoose schema can be accessed in the schemaCallback function, if provided in the options. This can be used to add indexes, static methods, etc, before the model is created.

Built With

Contributing

This is not yet open for public contribution. If you find any bugs or wish to request a feature, please add to any existing relevant tickets or add your own bug or feature request.

Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

Authors

  • Henry Mcintosh

See also the list of contributors who participated in this project.

License

This project is licensed under the MIT License - see the LICENSE file for details