@beardedtim/cruddy
TypeScript icon, indicating that this package has built-in type declarations

0.0.5 • Public • Published

Cruddy

Overview

cruddy is a tool to help build CRUD interfaces with JSON Schema validation.

Usage

You can find a working demo at demo.js but you will have to ensure that your DB is working or use the docker-compose file in this repo. How to do that is beyond this package's forte.

const { createServer } = require('@beardedtim/cruddy')

const server = createServer({
  /**
   * A configuration object that describes the types of our data
   */
  config: {
    // How this service will log and explain itself
    serviceName: 'CRUDDY_EXAMPLE',
    apiPrefix: '/api',
    // Where are we serving static content from?
    staticDir: 'public',
    // Path to the directory that holds all templates
    templateDir: './views',
    // What type of templating engine are you using?
    templateType: 'pug',
    domains: {
      // The name to add to the api
      users: {
        schemas: {
          // We can format the input and output of our requests
          // using the formatters block inside of schemas of the
          // domain
          formatters: {
            /**
             * This is the same keys as the schemas of create, readOne, readMany, update, destroy
             * and each key has an input and output function
             */
            create: {
              // This is given the Request object
              input: async req => {
                const { password, ...user } = req
                const hashed = await hashPassword(password)

                return {
                  ...user,
                  password: hashed
                }
              }
            },
            readMany: {
              output: users => ...
            },
            update: {
              // This is given whatever the DB call would return
              // since it's an update, it will be a single user
              output: user => ({
                ...user,
                some_formatted_key: true
              })
            }
          }
          // Create Read Update Destroy schemas.
          // All schemas default to accepting _anything_
          create: {
            /**
             * Some JSON Schema describing the body expected
             * for create
             */
          },
          readMany: {
            /**
             * Some JSON Schema describing the query expected
             * for readMany
             */
          },
          readOne: {
            /**
             * Some JSON Schema describing the query expected
             * for readOne
             */
          },
          update: {
            /**
             * Some JSON Schema describing the body expected
             * for update
             */
          },
          destroy: {
            /**
             * Some JSON Schema describing the query expected
             * for delete
             */
          },
          /**
           * Sometimes we only want to return certain keys from this
           * item. This allows us to set that. It can be a single key
           * or an array of keys. '*' means all keys
           *
           * We don't want to return the email _EVER_ from the API
           * so we create a list of keys that we want to return
           */
          keys: ['id', 'email', 'created_at', 'last_updated']
        },

        views: {
          // Create Read Update Destroy views.
          create: {
            /**
             * Some View Schema describing the body expected
             * for create
             */
          },
          readOne: {
            /**
             * Some View Schema describing the query expected
             * for reading one item
             */
          },
          readMany: {
            /**
             * Some View Schema describing the query expected
             * for reading many items
             */
          },
          update: {
            /**
             * Some View Schema describing the body expected
             * for update
             */
          },
          destroy: {
            /**
             * Some View Schema describing the query expected
             * for delete
             */
          }
        }
      }
    }
  },
  /**
   * The pages that we want to serve that aren't based
   * on CRUD
   */
  pages: {
    template: 'some-template',
    path: '/',
    data: context => Promise.resolve({})
  },
  /**
   * The configuration object for the DB. Currently gets passed
   * as-is to Knex
   */
  db: {
    client: 'postgres',
    // You can also use a string here if you have the URL
    // postgres://hello.com:2345/something
    connection: {
      host: 'abc.com',
      port: 5432,
      user: 'username',
      password: '123!',
      database: 'enough'
    }
  },
  /**
   * Any middleware that we want to be ran before any of the handlers
   * but after the global middleware such as CORS/Helmet/etc
   */
  preware: [],
  /**
   * Any middleware that we want to be ran after all the other handlers
   */
  postware: [],
  /**
   * How you want to format any errors before sending them to the client
   */
  onError: () => {},
  /**
   * How you want to format any data before sending it to the client
   */
  onSuccess: () => {}
})

server.listen(5000, () => server.log.info('Service has started'))

Exposed Routes

Given a domain object of

const domain = {
  users: {
    schemas: {},
    views: {}
  },
  posts: {
    schemas: {},
    views: {}
  }
}

this tooling will create the following routes:

# View Specific
GET /users
GET /users/create
GET /users/:id
GET /users/:id/edit
GET /users/:id/destroy

GET /posts
GET /posts/create
GET /posts/:id
GET /posts/:id/edit
GET /posts/:id/destroy


# API Specific
GET /api/users
POST /api/users
GET /api/users/:id
PATCH /api/users/:id
DELETE /api/users/:id

GET /api/posts
POST /api/posts
GET /api/posts/:id
PATCH /api/posts/:id
DELETE /api/posts/:id

It will ensure that the body (for patch or post requests) or query (for all other requests) of the requests passes the schema for the API endpoints called out by the schemas key. It will also call the templates called out by views key.

It will return the keys per the configuration in the schema OR allow you to select keys via the query args. However, you can choose not to allow the keys query arg via the JSON Schema

Readme

Keywords

none

Package Sidebar

Install

npm i @beardedtim/cruddy

Weekly Downloads

0

Version

0.0.5

License

MIT

Unpacked Size

61.5 kB

Total Files

25

Last publish

Collaborators

  • beardedtim