1.0.0 • Published 5 years ago

coroo-bcknd-mdls v1.0.0

Weekly downloads
3
License
UNLICENSED
Repository
github
Last release
5 years ago

Back-end Modules

Version

v3.2.1

Install

npm i @futuready/fib-backend-modules

Usage

require(`@futuready/fib-backend-modules/lib/MODULE_NAME`);

array-utils.js - Utilities for Array.

  • reduce (array: any[], callback: value => value, { caseKind: string = undefined, destructure: boolean = false } = {}): object

    Reduce an array into an object.

    • array (any[])

      The source array to be reduced. Expects a homogeneous element of array.

    • callback (value => value)

      The provided function for each value to return the result.

    • options (object): Optional options.

      • caseKind (string: `camelCase`|`pascalCase`)

        Kind of casing for keys. If not set it will leave the keys as is. Defaults to undefined.

      • destructure (boolean)

        If true the resulting value will be destructured. Defaults to false.

    See MDN - Array.prototype.reduce().

    const { reduce } = require(`@futuready/fib-backend-modules/lib/array-utils`);
    
    const languages = [`en`, `id`];
    
    const pojo = reduce(languages, language => language.toUpperCase());
    console.log(JSON.stringify(pojo, null, 2));
    
    /* Output result:
    {
    id: `ID`,
    en: `EN`
    }
    */
    
    const classes = [
      { Lossy: class Lossy {} }
      { Translatable: class Translatable {} }
    ];
    
    const destructrued = reduce(classes, value => value, { destructure: true });
    console.log(JSON.stringify(destructrued, null, 2));
    
    /* Output result:
    {
    Lossy: class Lossy {}
    Translatable: class Translatable {}
    }
    */

mixins.js - Utilities for Mixin.

  • mix (Base: class): object

    • with (...Mixins: mixin): class

      Combine mixins to extend the base class.

      const { mix } = require(`@futuready/fib-backend-modules/lib/mixins`);
      
      class BaseClass {
        // ...
      }
      
      const Disposable = Base => (
        class extends Base {
          dispose() {
            // ...
          }
        }
      );
      
      const Activatable = Base => (
        class extends Base {
          get isActive() {
            // ...
          }
        }
      );
      
      class Model extends mix(BaseClass).with(Disposable, Activatable) {
        dispose() {
          // ...
        }
        get isActive() {
          // ...
        }
      }

object-utils.js - Utilities for Object & Class.

  • hasProperty (owner: object, name: string): boolean

    Check if an object has its own property.

    • owner (object)

      The object to be inspected.

    • name (string)

      The name of property to check.

    See MDN - Object.prototype.hasOwnProperty().

    const { hasProperty } = require(`@futuready/fib-backend-modules/lib/object-utils`);
    
    const person = {
      firstName: `John`
    };
    
    console.log(hasProperty(person, `firstName`)); // true
  • defineProperty (owner: object, name: string, { enumerable: boolean = true, configurable: boolean = true, writable: boolean = true, value: any = undefined, get: function() = undefined, set: function(value) = undefined })

    Defines property of an object.

    • owner (object)

      The object for the property to be defined.

    • name (string)

      The name of property to be defined.

    • options (object): Optional options.

      • enumerable (boolean)

        If set to false the property will be hidden.

      • configurable (boolean)

        If set to false the property won't be able to delete.

      • writable (boolean)

        If set to false the property will be read-only. Can't be set if get or set is defined.

      • value (any)

        The value for the property. Can't be set if get or set is defined.

      • get (function())

        The getter for the property. Can't be set if value or writable is defined.

      • set (function(value))

        The setter for the property. Can't be set if value or writable is defined.

    See MDN - Object.defineProperty().

    const {
      hasProperty,
      defineProperty
    } = require(`@futuready/fib-backend-modules/lib/object-utils`);
    
    const person = {
      firstName: `John`
    };
    
    defineProperty(person, `lastName`, { value: `Doe` });
    console.log(JSON.stringify(person, null, 2));
    
    /* Output result:
    {
    firstName: `John`,
    lastName: `Doe`
    }
    */
  • defineHiddenProperty (owner: object, name: string, { configurable: boolean = true, writable: boolean = true, value: any = undefined, get: function() = undefined, set: function(value) = undefined })

    Defines a hidden property of an object. A wrapper for defineProperty with enumerable is set to false.

  • defineImmutableProperty (owner: object, name: string, { configurable: boolean = true, enumerable: boolean = true, value: any = undefined, get: function() = undefined, set: function(value) = undefined })

    Defines a read-only property of an object. A wrapper for defineProperty with writable is set to false.

  • defineClass (Class: class): class

    Defines an anonymous class that retains its static name property.

    • Class (class)

      The class to be defined.

    const { defineClass } = require(`@futuready/fib-backend-modules/lib/object-utils`);
    
    class Person {}
    
    console.log(Person.name); // Person
    
    const Translatable = Model => (
      class extends Model {}
    );
    
    let model = class extends Translatable(Person) {};
    console.log(model.name); // should be `Person` but instead printed as `model`.
    
    model = defineClass(class extends Translatable(Person) {});
    
    console.log(model.name); // Person
  • assign ( target: object, sources: object): (`object)

    Returns an object or class which will be overriden by the target. It's used to copy the values of all enumerable own properties from one or more source objects to target object or class.

    See MDN - Object.assign().

    • target (object)

      The object to be extended.

    • sources (object)

      The sources giving the override.

    const { assign } = require(`@futuready/fib-backend-modules/lib/object-utils`);
    
    const object = {
      value: 1,
      qty: 1,
      calculate() {
        return this.qty;
      }
    };
    
    const Base = assign(class {}, object);
    
    class MyClass extends Base {
      static get value() {
        return 2 + super.qty;
      }
    
      static calculate() {
        return this.value + super.calculate();
      }
    }
    
    // Output: 4
    console.log(MyClass.calculate());

case-converter.js - Case Converter.

  • camelCase (string: string): string

    Returns camel cased casing.

  • pascalCase (string: string): string

    Returns pascal cased casing.

  • snakeCase (string: string): string

    Returns snake cased casing.

  • kebabCase (string: string): string

    Returns kebab cased casing.

    const {
      snakeCase,
      kebabCase,
      camelCase,
      pascalCase,
    } = require(`@futuready/fib-backend-modules/lib/case-converter`);
    
    console.log(snakeCase(`array-utils`)); // array_utils
    console.log(kebabCase(`array_utils`)); // array-utils
    console.log(camelCase(`array-utils`)); // arrayUtils
    console.log(pascalCase(`array-utils`)); // ArrayUtils

compose.js - Middleware Composer.

Composer for middleware inspired by Koa's middleware. It enables down-stream up-stream flow of execution.

Middleware Signature

async function middleware(ctx, next) {
  const {
    input,
    output,
  } = ctx;

  console.log(input);
  console.log(output);

  await next();
}
  • ctx: object

    • input: object

      Use it as data store for request.

    • output: object

      Use it as data store for response.

    • done: boolean

      If set to true it will exit once the current running middleware is done executed (once await next() is called), so that the rest of the middlewares won't be executed. Set this value before calling await next(). Don't use this as a replacement for throwing an error.

  • next: AsyncFunction

    Always call await next() after you're done, so that the next middleware will be executed.

Example

service.js

const compose = require(`@futuready/fib-backend-modules/lib/compose`);

const Person = require(`./models/person`);

async function validation(ctx, next) {
  const { input } = ctx;

  if (input.name !== `John`) throw new Error(`NOT_EXIST`);

  await next();
}

async function processing(ctx, next) {
  const {
    input,
    output,
  } = ctx;

  const person = (
    await Person
      .query()
      .where(input)
  );

  /* Example result:
  {
    firstName: `John`,
    lastName: `Doe`
  }
  */

  output = person;

  await next();
}

async function transform(ctx, next) {
  const { output } = ctx;

  output = Object.keys(output).reduce((result, key) => ({
    ...result,
    [key]: output[key].toUpperCase(),
  }), {});

  await next();
}

module.exports = {
  list: compose(validation, processing, transform),
};

controller.js

const { list: listService } = require(`./service.js`);

async function list() {
  const result = await listService({ name: `John` });
  console.log(result);

  /* Output result:
  {
    firstName: `JOHN`,
    lastName: `DOE`
  }
  */
}

imports.js - Auto-loader for importing modules from inside a directory.

Convenience function to autoload modules from source directory.

  • sourceDir (string): The absolute path of the directory that will be imported as modules. Use __dirname for loading the current directory.

  • options (object): Optional options.

    • onlyImporting (boolean):

      If true the imported modules are loaded but won't be returned as the result. Defaults to false.

    • destructure (boolean):

      If true the imported result will be destructured. Defaults to false.

    • excludedFilenames (string[]):

      List of excluded filenames. Defaults to `index.js`.

    • includedExtensions (string[]):

      List of included file extensions. Defaults to `.js`.

    • importSubdirsAsModules (boolean):

      Imports sub directories that has index.js file. Defaults to false.

    • excludedDirectories (string[]):

      List of excluded directories when including sub directory as modules.

    • caseKind (string: `camelCase`|`pascalCase`):

      Kind of naming case to be used as the result. Defaults to `camelCase`.

Example

Directory structure:

models
|-- index.js
|-- customer.js
|-- product.js

customer.js

class Customer {}
module.exports = { Customer };

person.js

class Person {}
module.exports = { Person };

index.js

module.exports = require(`@futuready/fib-backend-modules/lib/imports`)(__dirname, { caseKind: `pascalCase`, destructure: true });
/* Expected result when imported:
{
  Customer,
  Person,
}
*/

const {
  Customer,
  Person,
} = require(`./models);

exception.js - Exception Classes.

  • Exception

    Base Exception class. Accepts data to store properties.

    const { Exception } = require(`@futuready/fib-backend-modules/lib/exception`);
    
    try {
      throw new Exception({ message: `File is not exist.`, data: { key: `NOT_EXIST` } });
    } catch (err) {
      console.log(err.message); // `File is not exist.`
      console.log(err.data); // { key: `NOT_EXIST` }
    }
  • ParsableException

    Replaces tokens in message with provided values.

    const { ParsableException } = require(`@futuready/fib-backend-modules/lib/exception`);
    
    try {
      throw new HttpException({
        message: `$0 is not exist.`,
        values: [`File`],
        data: { key: `NOT_EXIST` },
      });
    } catch (err) {
      console.log(err.message); // `File is not exist.`
      console.log(err.data); // { key: `NOT_EXIST` }
    }
  • HttpException

    Accepts code to used as HTTP status code (4xxx, 5xxx).

    const { HttpException } = require(`@futuready/fib-backend-modules/lib/exception`);
    
    try {
      throw new HttpException({
        code: 400,
        message: `$0 is not exist.`,
        values: [`File`],
        data: { key: `NOT_EXIST` },
      });
    } catch (err) {
      console.log(err.message); // `File is not exist.`
      console.log(err.code); // 400
      console.log(err.data); // { key: `NOT_EXIST` }
    }