Necessary Pigeonholing Mechanism
    Have ideas to improve npm?Join in the discussion! »

    deep-key-mirror
    TypeScript icon, indicating that this package has built-in type declarations

    0.2.3 • Public • Published

    Deep Key Mirror

    npm version Build Status David Test Coverage Code Climate License

    Alternative to React's keyMirror

    Installation

    npm install deep-key-mirror

    Usage

    deepKeyMirror(any, [config])

    Constructs an enumeration with keys equal to their value.

    If the given object has child arrays or objects, they are also "key-mirrored" recursively, with the '.'-concatenated paths from the root object assigned to each of their value.

    example

    let breakfast = {
      bread: null,
      beverage: {
        milk: null,
        coffee: null,
        beer: "BEER!"
      },
      fruits: [
        'orange',
        'apple'
      ]
    };
    let breakfastConfig = deepKeyMirror(breakfast);
    /*
    breakfastConfig === {
      bread: 'bread',
      beverage: {
       milk: 'beverage.milk',
       coffee: 'beverage.coffee',
       beer: 'beverage.BEER!'
      },
      fruits: {
        orange: 'fruits.orange',
        apple: 'fruits.apple'
      }
    }
    */
     

    matrix(string[][], [config])

    Creates an isomorphic and recursive key-value structure. Consider the Redux scenario below:

    You have a RESTful API with the following specification:

    • The API can manipulate 3 types of resources; user, team and group
    • Each of them can be manipulated by these operations; GET, POST, PUT, and DELETE
      e.g. for user resource manipulation, there are totally 5 API endpoints:
      • POST /users to create a user
      • GET /users to retrieve a user list
      • GET /users/:id to retrieve a specified user
      • PUT /users/:id to update a specified user
      • DELETE /users/:id to delete a specified user
    • In order to represent asynchronous API calls in Redux, there are 3 action types per each endpoint.
      • request action: happens when api call has been fired
      • success action: happens when api call has been completed with success
      • failure action: happens when api call has been completed with failure

    To create all of action types to meet the requirements above, you can simply write as follows:

    example

    let restApi = matrix([
      ['user', 'team', 'group'],
      ['get', 'getList', 'post', 'put', 'delete'],
      [ 'request', 'success', 'failure' ]
    ]);
    /*
     restApi === {
       user: {
         get:     { request: 'user.get.request',      success: 'user.get.success',      failure: 'user.get.failure' },
         getList: { request: 'user.getList.request',  success: 'user.getList.success',  failure: 'user.getList.failure' },
         post:    { request: 'user.post.request',     success: 'user.post.success',     failure: 'user.post.failure' },
         put:     { request: 'user.put.request',      success: 'user.put.success',      failure: 'user.put.failure' },
         delete:  { request: 'user.delete.request',   success: 'user.delete.success',   failure: 'user.delete.failure' },
       },
       team: {
         get:     { request: 'team.get.request',      success: 'team.get.success',      failure: 'team.get.failure' },
         getList: { request: 'team.getList.request',  success: 'team.getList.success',  failure: 'team.getList.failure' },
         post:    { request: 'team.post.request',     success: 'team.post.success',     failure: 'team.post.failure' },
         put:     { request: 'team.put.request',      success: 'team.put.success',      failure: 'team.put.failure' },
         delete:  { request: 'team.delete.request',   success: 'team.delete.success',   failure: 'team.delete.failure' },
       },
       group: {
         get:     { request: 'group.get.request',     success: 'group.get.success',     failure: 'group.get.failure' },
         getList: { request: 'group.getList.request', success: 'group.getList.success', failure: 'group.getList.failure' },
         post:    { request: 'group.post.request',    success: 'group.post.success',    failure: 'group.post.failure' },
         put:     { request: 'group.put.request',     success: 'group.put.success',     failure: 'group.put.failure' },
         delete:  { request: 'group.delete.request',  success: 'group.delete.success',  failure: 'group.delete.failure' },
       }
     }
     */
     
    // actions/getTeam.js
    let restApi = ...;
    let { request, success, failure } = restApi.team.get;
     
    // get team
    export default id => dispatch => {
      dispatch({
        type: request,
        payload: { id }
      });
      teamService
        .getTeamById(id)
        .then((team) =>
          dispatch({
            type: success,
            payload: { team }
          })
        , (failure) =>
          dispatch({
            type: failure,
            error: true,
            payload: { failure }
          })
        );
    };

    config

    Both deepKeyMirror and matrix can take config object as a second argument, which has these three options

    prop type default description
    prependKeyPath boolean true When set to true and if deepKeyMirror find a string value during object traversal, it uses the string prepended by concatenated object path as its mirrored path.
    keyJoinString string '.' Separator for joining object paths.
    makeUpperCase boolean false When set to true, values will be mirrored with uppercase.

    examples

    let props = {
      color: {
        red: null,
        green: null,
        blue: 'not_an_yellow',
        other: {
          brown: 'maroon'
        }
      }
    };
     
    let propConfig = deepKeyMirror(props, { prependKeyPath: true });
    /*
    props = {
      color: {
        red: 'color.red',
        green: 'color.green',
        blue: 'color.not_an_yellow',
        other: {
          brown: 'color.other.maroon'
        }
      }
    };
    */
     
    let propConfig = deepKeyMirror(props, { prependKeyPath: false });
    /*
    props = {
      color: {
        red: 'color.red',
        green: 'color.green',
        blue: 'not_an_yellow',
        other: {
          brown: 'maroon'
        }
      }
    };
    */
     
    let propConfig = deepKeyMirror(props, { keyJoinString: '-' });
    /*
    props = {
      color: {
        red: 'color-red',
        green: 'color-green',
        blue: 'color-not_an_yellow',
        other: {
          brown: 'color-other-maroon'
        }
      }
    };
    */
     
    let propConfig = deepKeyMirror(props, { makeUpperCase: true });
    /*
    props = {
      color: {
        red: 'COLOR.RED',
        green: 'COLOR.GREEN',
        blue: 'COLOR.NOT_AN_YELLOW',
        other: {
          brown: 'COLOR.OTHER.MAROON'
        }
      }
    };
    */

    TypeScript

    TypeDoc-generated documentation is available here

    Install

    npm i deep-key-mirror

    DownloadsWeekly Downloads

    0

    Version

    0.2.3

    License

    MIT

    Last publish

    Collaborators

    • avatar