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

scrud

v9.0.0

Published

SCRUD API server, fast, light, capable

Downloads

44

Readme

scrud NPM version js-standard-style

SCRUD API server, fast, light, capable

what is SCRUD

It's just CRUD with a search action included in the package.

  • search
  • create
  • read
  • update
  • delete

Every resource has corresponding SCRUD actions which are expressed in the HTTP methods and path (resource ids and query params).

what is this module

  • a performance minded API server
  • a resourceful SCRUD based router
  • a collection of tools that allow you to stand up APIs rapidly
  • opinionated
  • full featured (PG, gzip, CORS, and JWT fully integrated)
  • a wire between your SCRUD PostgreSQL functions and the client

who is it for

  • me mostly
  • folks who need an effective resource driven API server
  • organizations / individuals who like PostgreSQL and need a solid frontend

install

$ npm install --save scrud

usage

const scrud = require('scrud')
const config = require('./secrets.json')

async function main () {
  const memberHandler = {
    update: (req, res) => scrud.sendData(res, 'not updated, goteem'),
    delete: (req, res) => scrud.sendErr(res, new Error('Resource cannot be deleted')),
    beforeQuery: {
      search: (req, res) => {
        delete req.params.someProperty
        return Promise.resolve()
      }
    },
    beforeSend: {
      read: (req, res, data) => {
        data.meaningOfLife = 42
        return Promise.resolve(data)
      }
    }
  }

  scrud.register('member', memberHandler)
  await scrud.start(config)
}

api

scrud.register(name, handlers)

  • Registers a resource as an API, enabling it to respond to SCRUD actions against it
  • A common pattern would be registering resources that correlate to database tables
  • Does not have to correlate to a database table
  • If actions handlers are not specified then matching PG functions for each action are required
  • Each PG function matches pattern ${namespace}_${resource}_${action}(IN jsonb, OUT jsonb)
  • PG functions receive JSONB object containing the following
    • auth - auth object (i.e. JWT payload)
    • ip - (if getIp enabled) client IP address
    • id - resource id for READ, UPDATE, DELETE
    • id_array - array of single resource id for READ
    • anything passed as querystring or in JSON body will be passed along and should be validated / escaped within PG functions
  • PG functions are expected to reply with an array of records in JSONB format
  • All PG functions should reply with array, even if they act on single resource

Returns: Promise which with resolves with resource object

Arguments:

  • name - String - required - (name of resource) example: 'user'
  • handlers - Object - optional
    • example: { read: (req, res) => scrud.sendData(res, req.params.id) }
    • search, create, read, update, delete - optional
      • type: async Function
      • receives: (http.ClientRequest, http.ServerResponse)
      • default: calls ${namespace}_${resource}_${action}(IN jsonb, OUT jsonb) PG function and responds to client with array of records or error
    • beforeQuery - Object - optional
      • example: { beforeQuery: { delete: async (req, res) => scrud.logIt(req.ip, 'debug') } }
      • search, create, read, update, delete - optional
        • type: async Function
        • receives: (http.ClientRequest, http.ServerResponse)
        • should return: Promise
        • default: null
        • IMPORTANT: If a Promise isn't returned or doesn't resolve or reject and the function doesn't close the response it will be hung
    • beforeSend - Object - optional
      • example: { beforeSend: { read: (req, res, data) => Promise.resolve('hello') } }
      • search, create, read, update, delete - optional
        • type: async Function
        • receives: (http.ClientRequest, http.ServerResponse, data)
        • should return: Promise that resolves with data to be sent to client
        • default: null
        • IMPORTANT: If a Promise isn't returned or doesn't resolve or reject and the function doesn't close the response it will be hung. Also, the data that is sent in the promise resolution will be passed to the client, be sure it's what you intend to send.
    • onError - Object - optional
      • example: { onError: { read: (req, res, error) => scrud.sendErr(error) } }
      • search, create, read, update, delete - optional
        • type: Function
        • receives: (http.ClientRequest, http.ServerResponse, error)
        • should return: doesn't matter
        • default: null
        • IMPORTANT: You need to respond to the client so their request isn't hung
    • pg - Object - optional - PG connection specific to resource
      • search, create, read, update, delete - optional
        • type: pg.Pool
        • default: null

scrud.start(options)

Set global options and start API server

Returns: Promise which with resolves with http.Server

Arguments:

  • options - Object - required
    • registerAPIs - optional - mass API registration, alternative to scrud.register
      • type: Array of either Strings (resource name) or Object of type { name, handlers }
      • default: null
    • basePath - optional - base path for APIs (i.e. https://host.com/${basePath}/resource)
      • type: String
      • default: null
    • namespace - optional - namespace to use in PG function calls (i.e. ${namespace}_${resource}_${action}). If not set the PG function called will be ${resource}_${action}
      • type: String
      • default: null
    • postgres - required if using DB backed actions - configuration for node-postgres connection
      • type: Object matching config specs for node-postgres
      • default: null
    • jsonwebtoken - required for JWT authentication - configuration for jsonwebtoken connection
      • type: Object that contains options from both the sign and verify methods at jsonwebtoken
      • default: null
    • maxBodyBytes - optional - max bytes allowed from incoming request body
      • type: Integer (bytes)
      • default: 1e6
    • logger - optional - callback that will get called with any errors encountered
      • type: Function - receives (Error, String[loglevel])
      • default: console.log
    • getIp - optional - should client IP be added to request object
      • type: Boolean
      • default: false
    • useNotModified - optional - if hash-wasm is installed as peer-dependency use it to calculate hash of JSON body and send 304 if matched
      • type: Boolean
      • default: false
    • authTrans - optional - Synchronous function that transforms the passed in auth object before proceeding with processing
      • type: Function - receives (Object[auth / JWT payload)])
      • default: null
      • returns: Object - updated auth object

helper functions (used internally but exported as a courtesy)

generic helpers

  • shutdown() - close server and end open database connections
  • sendData(response, data, request) - send response data to client
  • sendErr(response, error, code) - send error to client
  • fourOhOne(response, error) - send 401 (unauthorized) error to client
  • fourOhFour(response, error) - send 404 (not found) error to client
  • genToken(payload) - generate JWT token
  • authenticate(jwt) - authenticate JWT token
  • logIt(error, logLevel) - invoke logger with error and logLevel
  • callPgFunc(functionName, params, request) - call any PG function with single arg

database action helpers

  • findAll(resource, request) - call PG search function for resource
  • insert(resource, request) - call PG create function for resource
  • find(resource, request) - call PG read function for resource
  • save(resource, request) - call PG update function for resource
  • destroy(resource, request) - call PG delete function for resource

scrud helpers

  • search(resource, request) - run registered search handler for resource
  • create(resource, request) - run registered create handler for resource
  • read(resource, request) - run registered read handler for resource
  • update(resource, request) - run registered update handler for resource
  • delete(resource, request) - run registered delete handler for resource

related

get-scrud - A handy client for SCRUD APIs, backed by axios

license

MIT © Andrew Carpenter