0.0.2 • Published 2 years ago

ywemay-api-crud v0.0.2

Weekly downloads
-
License
ISC
Repository
github
Last release
2 years ago

API Crud

Helper class/functions to build a CRUD controller.

Example:

Controller definition

// controllers/example.js

// import controller builder class and helper functions
const { Controller, expand, compact } = require("../../index");
// import example model - mongoose defined model (consult mongoose documentation)
const model = require("../models/Example");
// import yup for field validation
const yup = require("yup");
// import role constants and hasRole function to check access
const {
  ADMIN,
  MANAGER,
  SELLER,
  CUSTOMER,
  hasRole,
} = require("ywemay-api-role");

// define validation schema (consult you package documentation)
const schema = yup.object().shape({
  name: yup.string().min(2).max(30).required(),
  tags: yup.array().of(
    yup.object().shape({
      id: yup.string().min(1).max(20),
    })
  ),
});

const Adv = new Controller({
  model,
  // security settings:
  security: {
    // everybody is allowed to list our Example list
    list: () => Promise.resolve(),
    // everybody is allowed to view our Example list
    view: () => Promise.resolve(),
    // only ADMIN, MANAGER and SELLER groups are allowed to post Example record
    post: ({ user }) => {
      return new Promise((resolve, reject) => {
        hasRole(user, [ADMIN, MANAGER, SELLER]) ? resolve({}) : reject();
      });
    },
    // only ADMIN, MANAGER and SELLER groups are allowed to update Example record
    put: ({ user }) => {
      return new Promise((resolve, reject) => {
        hasRole(user, [ADMIN, MANAGER, SELLER]) ? resolve({}) : reject();
      });
    },
    // ADMIN, MANAGER can delete any Example, SELLER can delete own Examples.
    delete: ({ user }) => {
      return new Promise((resolve, reject) => {
        if (hasRole(user, [ADMIN, MANAGER])) return resolve({});
        if (hasRole(user, [SELLER])) return resolve({ owner: user.uid });
        reject();
      });
    },
  },
  // validate schemas for received data before saving/updating
  validators: {
    post: ({ data }) => schema.validate(data),
    put: ({ data }) => schema.pick(Object.keys(data)).validate(data),
  },
  // what fields shall be included during list, getManyReference, view
  projections: {
    list: { name: true },
    references: { name: true },
    view: { name: true, tags: true },
  },
  hooks: {
    // item prepared for sending out from API
    expand: (item) => {
      if (Array.isArray(item.tags)) item.tags = expand(item.tags);
      return item;
    },
    // item prepared to be saved in db
    compact: (item) => {
      if (Array.isArray(item.tags)) item.tags = compact(item.tags);
      return item;
    },
  },
});

module.exports = Adv;

Using the controller in routes:

const {
  getList,
  getOne,
  getManyReference,
  create,
  update,
  updateMany,
  deleteOne,
  deleteMany,
} = require("../controllers/example");
const router = require("express").Router();
const { checkAuth, send } = require("ywemay-api-user");

router.use(checkAuth);

router.get("/", getList);
router.get("/id/:id", getOne);
router.get("/ref", getManyReference);
router.post("/", create);
router.put("/", updateMany);
router.put("/id/:id", update);
router.delete("/", deleteMany);
router.delete("/id/:id", deleteOne);

router.use(send);

module.exports = router;