4.0.8 • Published 8 years ago

babel-plugin-check-data-access v4.0.8

Weekly downloads
-
License
MIT
Repository
github
Last release
8 years ago

babel-plugin-check-data-access

npm version license semver build status total townloads

A babel plugin enabling automatic access-checks and convenient modification of immutable objects.

  • obj.a.b[2]deepAccess.get(obj, ["a", "b", 2])
  • set(obj.a.b, "value")obj = deepAccess.set(obj, ["a","b"], "value")

Transformation 1: Checking object access

obj.a.b will be transformed into a function call like deepAcc.get(obj, ["a", "b"]), which will throw an error if the property path obj → a → b is not found, if an array index is out of bounds and so on. deepAcc is an injected function-suite, the plugin ensures that the import doesn't collide.

More examples in the test-case: proxyMemberAccess_spec.js

Note: This will also throw on statements like if (obj.a.b) {…} if a.b isn't defined. You can use if (exists(obj.a.b)) {…}, which is semantically cleaner than the usage of truthy values.

Transformation 2: Enabling special functions:

  • Getters: get, exists, collect, select
  • Setters: set, del, replace, create, update, toggle, push, patch

These allow to work on deep structures. Setters copy object if needed, the original object won't be touched. Substructures will be reused as often as possible.

create(x.a.b, 2) will become x = deepAcc.create(x, ["a", "b"], 2). If x.a.b exists the function will throw an error, otherwise it will be set to 2.

Note: The immutability approach implies that working on members of this is not possible since it can't be reassigned (e.g. this = deepAcc.set(this.a, 2) is not valid syntax).

Note: To avoid confusion, the plugin will throw an error if one of the special functions is already defined in your code.

Functionality of deepAccess:

This allows functions inside brackets to search through nested structures, enabling statements like this:

/* $ is the variable, I have my redux state in */

/* collect into array */
let soldProducts = collect(
  $.consumers[idx => idx === selectedConsumer]    /* select idx in consumers array */
   .invoices[() => true]                          /* all invoices of that consumer */
   .products[() => true]                          /* all products inside those invoices */
); /* --> array of products */

/* selects member, throws if not exactly one is found */
let firstSoldProduct = select(
  $.consumers[idx => idx === selectedConsumer]
   .invoices[0]
   .products[0]
);

The other functions are:

get($.consumers)          /* throws if 'consumers' is not found in '$' or '$' is not an object */
get($.consumers, [])      /* get 'consumers' and return empty array if not found */
exists($.consumers)       /* --> true/false */
create($.consumers, [])   /* create: throws if member exists */
set($.consumers, [])      /* set: replace if member exists */
replace($.consumers, [])  /* replace: throws if member does not exist */
del($.consumers[0])       /* deletes first item in $.consumer */
toggle($.selected, idx)   /* delete if idx exists in $.selected, set it otherwise */

/* updates name of first consumer by running it through a function */
update($.consumers[0].name, name => name.toUpperCase())

/* pushes newConsumer to $.consumers, throws if it's not array or doesn't exist */
push($.consumers, newConsumer)

/* patch: add/replaces properties
          sets name of first consumer to newName
          throws if last consumer does not exist or is not an object */
patch($.consumers[0], {
  name: newName,
});

Spec: deepAccess_spec.js

Usage / Options

Put this in your .babelrc:

plugins: [
    ["check-data-access", {
        disableAccessChecks: false,
        disableSpecialFunctions: false,
        /* or just disable just some special functions */
        disableSpecialFunctions: ["create"]
    }]
 ]

Caveats

  • Access by providing functions currently only works for collect and select. Setting, deleting and updating multiple values will be added in the future.
  • patch doesn't apply recursively.

Changelog

  • v4.0.8 updated dependencies
  • v4.0.7 updated .publishrc
  • v4.0.6 moved testing from mocha and chai to tape
  • v4.0.5 updated README and keywords
  • v4.0.4 updated dependencies and whitelistes files in package.json
  • v4.0.3 performance improvements and don't throw if accessing string properties on arrays
  • v4.0.0 removed access with negative array indices. It's too easy to introduce bugs and it would change behaviour when disable the access-checks for production.
  • v3.0.1 fixed a wrong warning about 'get' being bound.
  • v3.0.0 reverted the previous change. Immutable objects are much more useful than the disadvantage of not being able to use setters on this.
  • v2.0.0 special functions don't copy and assign, but work on objects directly.
4.0.8

8 years ago

4.0.7

8 years ago

4.0.6

8 years ago

4.0.5

8 years ago

4.0.4

8 years ago

4.0.3

8 years ago

4.0.2

8 years ago

4.0.1

8 years ago

4.0.0

8 years ago

3.0.1

8 years ago

3.0.0

8 years ago

2.0.1

8 years ago

2.0.0

8 years ago

1.2.1

8 years ago

1.2.0

8 years ago

1.1.1

8 years ago

1.1.0

8 years ago

1.0.8

8 years ago

1.0.7

8 years ago

1.0.6

8 years ago

1.0.5

8 years ago

1.0.4

8 years ago

1.0.3

8 years ago

1.0.2

8 years ago

1.0.1

8 years ago

1.0.0

8 years ago