Repository: ViacomInc/data-point (js)

Issue:
Simplify DataPoint's API helpers/entity access
<!--
Thanks for your interest in the project. We appreciate bugs filed and PRs submitted!
Please make sure that you are familiar with and follow the Code of Conduct for
this project (found in the CODE_OF_CONDUCT.md file).

Please fill/un-comment out this template with all the relevant information so we can
understand what's going on and fix the issue.
-->

**Problem description**:

Requiring entities and helpers from DataPoint is currently a bit convoluted:

```js
const {Model, Request} = require('data-point').entities
const {constant, map} = require('data-point').helpers

// or 

const DataPoint = require('data-point')
const {Model, Request} = DataPoint.entities
const {constant, map} = DataPoint.helpers

// or 

const DataPoint = require('data-point')
DataPoint.entities.Model
DataPoint.entities.Request
DataPoint.helpers.constant
DataPoint.helpers.map

```

**Suggested solution**:

Simplify the access to these helpers/entities by changing the API to expose all entities and helpers from within the main module:

```js
const {
  Model, 
  Request,
  constant,
  map
} = require('data-point')

// or

const DataPoint = require('data-point')

DataPoint.Model
DataPoint.Request
```

Essentially the change is from: 

https://github.com/ViacomInc/data-point/blob/dac2133911173e3b9ab6ec4921a133a9b5c5f082/packages/data-point/lib/index.js#L8-L20

to this: 

```js
module.exports = {
  create: core.create,
  createEntity: helpers.createEntity,
  resolveEntity: helpers.resolveEntity,
  entityFactories: helpers.entityFactories,
  reducify: helpers.reducify,
  reducifyAll: helpers.reducifyAll,
  createReducer: helpers.createReducer,
  createReducerResolver: helpers.reducifyAll,
  createTypeCheckReducer,
  ...entities,
  ...helpers.helpers
}
```



Pull request:
feat(data-point): exposes helpers and entity factories via DataPoint
<!--
Thanks for your interest in the project. We appreciate bugs filed and PRs submitted!

Please make sure that you are familiar with and follow the Code of Conduct for
this project (found in the CODE_OF_CONDUCT.md file).

Also, please make sure you're familiar with and follow the instructions in the
contributing guidelines (found in the CONTRIBUTING.md file).

Please fill out the information below to expedite the review and (hopefully)
merge of your pull request!

BREAKING CHANGES:

If your PR includes a breaking change, please submit it with a codemod under
data-point-codemods that will help users upgrade their codebase.

Breaking changes without a codemod will not be accepted unless a codemod is not
viable or does not apply to the specific situation.
-->

<!-- What changes are being made? (What feature/bug is being fixed here?) -->
**What**:

exposes helpers and entity factories via DataPoint

<!-- Why are these changes necessary? -->
**Why**:

closes #314

<!-- How were these changes implemented? -->
**How**:

exposes helpers and entity factories via DataPoint
adds deprecation warnings for DataPoint.helpers and DataPoint.entities

<!-- Have you done all of these things?  -->
**Checklist**:
<!-- add "N/A" to the end of each line that's irrelevant to your changes -->
<!-- to check an item, place an "x" in the box like so: "- [x] Documentation" -->
- [ ] Has Breaking changes N/A
- [X] Documentation
- [X] Tests
- [X] Ready to be merged <!-- In your opinion, is this ready to be merged as soon as it's reviewed? -->
- [ ] Added username to **all-contributors** list N/A

<!-- feel free to add additional comments -->


Patch:
diff --git a/packages/data-point/README.md b/packages/data-point/README.md
index e7070a8..fca7f22 100644
--- a/packages/data-point/README.md
+++ b/packages/data-point/README.md
@@ -125,12 +125,9 @@ Based on an initial feed, fetch and aggregate results from multiple remote servi
   const {
     Request,
     Model,
-    Schema
-  } = DataPoint.entities
-
-  const {
+    Schema,
     map
-  } = DataPoint.helpers
+  } = DataPoint
 
   // schema to verify data input
   const PlanetSchema = Schema('PlanetSchema', {
@@ -748,7 +745,7 @@ Example at: [examples/reducer-function-error.js](examples/reducer-function-error
 These are plain objects where the value of each key is a [Reducer](#reducers). They're used to aggregate data or transform objects. You can add constants with the [constant](#reducer-constant) reducer helper, which is more performant than using a function reducer:
 
 ```js
-const { constant } = require('data-point').helpers
+const { constant } = require('data-point')
 
 const objectReducer = {
   // in this case, x and y both resolve to 42, but DataPoint
@@ -932,10 +929,10 @@ See the [Entities](#entities) section for information about the supported entity
   <summary>Entity Reducer Example</summary>
 
   ```js
-  const { 
-    Model, 
-    Request 
-  } = require('data-point').entities
+  const {
+    Model,
+    Request
+  } = require('data-point')
 
   const PersonRequest = Request('PersonRequest', {
     url: 'https://swapi.co/api/people/{value}'
@@ -1118,7 +1115,7 @@ Example at: [examples/reducer-conditional-operator.js](examples/reducer-conditio
 
 ## <a name="reducer-helpers">Reducer Helpers</a>
 
-Reducer helpers are factory functions for creating reducers. They're exposed through `DataPoint.helpers`:
+Reducer helpers are factory functions for creating reducers. They're accessed through the `DataPoint` Object:
 
 ```js
 const {
@@ -1129,7 +1126,7 @@ const {
   map,
   parallel,
   withDefault
-} = require('data-point').helpers
+} = require('data-point')
 ```
 
 ### <a name="reducer-assign">assign</a>
@@ -1154,17 +1151,13 @@ assign(reducer:Reducer):Object
   <summary>Add a key that references a nested value from the accumulator.</summary>
 
   ```js
-  const {
-    assign
-  } = DataPoint.helpers
-
   const input = {
     a: 1
   }
 
   // merges the object reducer with
   // accumulator.value
-  const reducer = assign({
+  const reducer = DataPoint.assign({
     c: '$b.c'
   })
 
@@ -1209,10 +1202,6 @@ map(reducer:Reducer):Array
   <summary>Apply a set of reducers to each item in an array</summary>
 
   ```js
-  const {
-    map
-  } = DataPoint.helpers
-
   const input = [{
     a: 1
   }, {
@@ -1220,7 +1209,7 @@ map(reducer:Reducer):Array
   }]
 
   // get path `a` then multiply by 2
-  const reducer = map(
+  const reducer = DataPoint.map(
     ['$a', (input) => input * 2]
   )
 
@@ -1257,15 +1246,11 @@ filter(reducer:Reducer):Array
   <summary>Find objects where path `a` is greater than 1</summary>
 
   ```js
-  const {
-    map
-  } = DataPoint.helpers
-
   const input = [{ a: 1 }, { a: 2 }]
 
   // filters array elements that are not
   // truthy for the given list reducer
-  const reducer = filter(
+  const reducer = DataPoint.filter(
     ['$a', (input) => input > 1]
   )
 
@@ -1301,15 +1286,11 @@ find(reducer:Reducer):*
   <summary>Find elements where path `b` resolves to _truthy_ value</summary>
 
   ```js
-  const {
-    map
-  } = DataPoint.helpers
-
   const input = [{ a: 1 }, { b: 2 }]
 
   // the $b reducer is truthy for the
   // second element in the array
-  const reducer = find('$b')
+  const reducer = DataPoint.find('$b')
 
   dataPoint
     .resolve(reducer, input) 
@@ -1343,8 +1324,6 @@ constant(value:*):*
   <summary>returning an object constant</summary>
 
   ```js
-  const { constant } = DataPoint.helpers
-
   const input = {
     a: 1,
     b: 2
@@ -1352,7 +1331,7 @@ constant(value:*):*
 
   const reducer = {
     a: '$a',
-    b: constant({
+    b: DataPoint.constant({
       a: '$a',
       b: 3
     })
@@ -1378,8 +1357,6 @@ constant(value:*):*
   <summary>reducers are not evaluated when defined inside of constants</summary>
 
   ```js
-  const { constant } = DataPoint.helpers
-
   const input = {
     b: 1
   }
@@ -1393,7 +1370,7 @@ constant(value:*):*
 
   // both the object and the path will be treated as
   // constants instead of being used to create reducers
-  reducer = constant({
+  reducer = DataPoint.constant({
     a: '$b'
   })
 
@@ -1424,9 +1401,7 @@ parallel(reducers:Array<Reducer>):Array
   <summary>resolving an array of reducers with parallel</summary>
 
   ```js
-  const { parallel } = DataPoint.helpers
-
-  const reducer = parallel([
+  const reducer = DataPoint.parallel([
     '$a',
     ['$b', (input) => input + 2] // list reducer
   ])
@@ -1463,14 +1438,12 @@ The default value is not cloned before it's returned, so it's good practice to w
 **EXAMPLE:**
 
 ```js
-const { withDefault } = DataPoint.helpers
-
 const input = {
   a: undefined
 }
 
 // adds a default to a path reducer
-const r1 = withDefault('$a', 50)
+const r1 = DataPoint.withDefault('$a', 50)
 
 dataPoint.resolve(r1, input) // => 50
 
@@ -1500,7 +1473,7 @@ See **[built-in entities](#built-in-entities)** for information on what each ent
 
 ### <a name="instance-entity">Instance Entity</a>
 
-Entities can be created with these factory functions:
+Entities can be created from these factory functions:
 
 ```js
 const {
@@ -1512,7 +1485,7 @@ const {
   Request,
   Control,
   Schema
-} = require('data-point').entities
+} = require('data-point')
 ```
 
 **SYNOPSIS**
@@ -1535,9 +1508,9 @@ Factory(name:String, spec:Object):EntityInstance
 
 ```js
 const DataPoint = require('data-point')
-const { Model } = DataPoint.entities
+const { Model } = DataPoint
 
-dataPoint = DataPoint.create()
+const dataPoint = DataPoint.create()
 
 const HelloWorld = Model('HelloWorld', {
   value: input => ({
@@ -1637,7 +1610,6 @@ To use built-in type checks, you may set the value of **inputType** or **outputT
 
   ```js
   const dataPoint = DataPoint.create()
-  const helpers = DataPoint.helpers
 
   dataPoint.addEntities({
     'model:getName': {
@@ -2245,7 +2217,6 @@ For more information on acc.locals: [Transform Options](#transform-options) and
 
   ```js
   const DataPoint = require('data-point')
-  const c = DataPoint.helpers.constant
   const dataPoint = DataPoint.create()
 
   dataPoint.addEntities({
@@ -2256,7 +2227,7 @@ For more information on acc.locals: [Transform Options](#transform-options) and
       // constants (or just wrap the whole
       // object if all the values are static)
       options: {
-        'content-type': c('application/json'), // constant
+        'content-type': DataPoint.constant('application/json')
         qs: {
           // get path `searchTerm` from input
           // to dataPoint.resolve
@@ -3564,7 +3535,7 @@ mocks()
 const {
   Model,
   Request
-} = DataPoint.entities
+} = DataPoint
 
 const PersonRequest = Request('PersonRequest', {
   url: 'https://swapi.co/api/people/{value}/'
diff --git a/packages/data-point/examples/entity-model-basic.js b/packages/data-point/examples/entity-model-basic.js
index c1ff7f0..60b7cd3 100644
--- a/packages/data-point/examples/entity-model-basic.js
+++ b/packages/data-point/examples/entity-model-basic.js
@@ -1,7 +1,7 @@
 const assert = require('assert')
 const DataPoint = require('../')
 
-const { Model } = DataPoint.entities
+const { Model } = DataPoint
 
 const input = {
   a: {
diff --git a/packages/data-point/examples/entity-request-options.js b/packages/data-point/examples/entity-request-options.js
index f1a0fb6..0cefc5e 100644
--- a/packages/data-point/examples/entity-request-options.js
+++ b/packages/data-point/examples/entity-request-options.js
@@ -3,7 +3,7 @@ const mock = require('./entity-request-options.mock')
 
 const DataPoint = require('..')
 
-const c = DataPoint.helpers.constant
+const c = DataPoint.constant
 const dataPoint = DataPoint.create()
 
 dataPoint.addEntities({
diff --git a/packages/data-point/examples/full-example-instances.js b/packages/data-point/examples/full-example-instances.js
index 39ca81b..638b955 100644
--- a/packages/data-point/examples/full-example-instances.js
+++ b/packages/data-point/examples/full-example-instances.js
@@ -4,9 +4,7 @@ const DataPoint = require('../')
 // create DataPoint instance
 const dataPoint = DataPoint.create()
 
-const { Request, Model, Schema } = DataPoint.entities
-
-const { map } = DataPoint.helpers
+const { Request, Model, Schema, map } = DataPoint
 
 // schema to verify data input
 const PlanetSchema = Schema('PlanetSchema', {
diff --git a/packages/data-point/examples/reducer-entity-instance.js b/packages/data-point/examples/reducer-entity-instance.js
index c5af8b0..88f4326 100644
--- a/packages/data-point/examples/reducer-entity-instance.js
+++ b/packages/data-point/examples/reducer-entity-instance.js
@@ -2,7 +2,7 @@ const assert = require('assert')
 
 const DataPoint = require('../')
 
-const { Model, Request } = DataPoint.entities
+const { Model, Request } = DataPoint
 
 const PersonRequest = Request('PersonRequest', {
   url: 'https://swapi.co/api/people/{value}'
diff --git a/packages/data-point/examples/reducer-helper-assign.js b/packages/data-point/examples/reducer-helper-assign.js
index 9026ef1..5aec55c 100644
--- a/packages/data-point/examples/reducer-helper-assign.js
+++ b/packages/data-point/examples/reducer-helper-assign.js
@@ -4,8 +4,6 @@ const assert = require('assert')
 const DataPoint = require('../')
 const dataPoint = DataPoint.create()
 
-const { assign } = DataPoint.helpers
-
 const value = {
   a: 1,
   b: {
@@ -15,7 +13,7 @@ const value = {
 
 // merges the ReducerObject with
 // the result with accumulator.value
-const reducer = assign({
+const reducer = DataPoint.assign({
   c: '$b.c'
 })
 
diff --git a/packages/data-point/examples/reducer-helper-filter.js b/packages/data-point/examples/reducer-helper-filter.js
index 8fbe9f8..bed0611 100644
--- a/packages/data-point/examples/reducer-helper-filter.js
+++ b/packages/data-point/examples/reducer-helper-filter.js
@@ -4,8 +4,6 @@ const assert = require('assert')
 const DataPoint = require('../')
 const dataPoint = DataPoint.create()
 
-const { filter } = DataPoint.helpers
-
 const value = [
   {
     a: 1
@@ -17,7 +15,7 @@ const value = [
 
 // filters array elements that are not
 // truthy for the given reducer list
-const reducer = filter(['$a', input => input > 1])
+const reducer = DataPoint.filter(['$a', input => input > 1])
 
 dataPoint.resolve(reducer, value).then(output => {
   assert.deepEqual(output, [{ a: 2 }])
diff --git a/packages/data-point/examples/reducer-helper-find.js b/packages/data-point/examples/reducer-helper-find.js
index 3609e23..0c66890 100644
--- a/packages/data-point/examples/reducer-helper-find.js
+++ b/packages/data-point/examples/reducer-helper-find.js
@@ -4,8 +4,6 @@ const assert = require('assert')
 const DataPoint = require('../')
 const dataPoint = DataPoint.create()
 
-const { find } = DataPoint.helpers
-
 const value = [
   {
     a: 1
@@ -17,7 +15,7 @@ const value = [
 
 // the $b reducer is truthy for the
 // second element in the array
-const reducer = find('$b')
+const reducer = DataPoint.find('$b')
 
 dataPoint.resolve(reducer, value).then(output => {
   assert.deepEqual(output, {
diff --git a/packages/data-point/examples/reducer-helper-map.js b/packages/data-point/examples/reducer-helper-map.js
index 9fef42f..dfc7ac4 100644
--- a/packages/data-point/examples/reducer-helper-map.js
+++ b/packages/data-point/examples/reducer-helper-map.js
@@ -4,8 +4,6 @@ const assert = require('assert')
 const DataPoint = require('../')
 const dataPoint = DataPoint.create()
 
-const { map } = DataPoint.helpers
-
 const value = [
   {
     a: 1
@@ -17,7 +15,7 @@ const value = [
 
 // applies the $a reducer to each
 // item in the array
-const reducer = map(['$a', input => input * 2])
+const reducer = DataPoint.map(['$a', input => input * 2])
 
 dataPoint.resolve(reducer, value).then(output => {
   assert.deepEqual(output, [2, 4])
diff --git a/packages/data-point/examples/registered-entities.js b/packages/data-point/examples/registered-entities.js
index 5bfae14..563b848 100644
--- a/packages/data-point/examples/registered-entities.js
+++ b/packages/data-point/examples/registered-entities.js
@@ -2,7 +2,6 @@ const assert = require('assert')
 const mocks = require('./async-example.mocks')
 const DataPoint = require('../')
 const dataPoint = DataPoint.create()
-const { map } = DataPoint.helpers
 
 dataPoint.addEntities({
   // remote service request
@@ -28,7 +27,7 @@ dataPoint.addEntities({
         // eg. https://swapi.co/api/people/1/
         // where each url gets mapped
         // to a model:Resident
-        residents: ['$residents', map('model:Resident')]
+        residents: ['$residents', DataPoint.map('model:Resident')]
       }
     ]
   },
diff --git a/packages/data-point/examples/trace.js b/packages/data-point/examples/trace.js
index 97189f2..fb34079 100644
--- a/packages/data-point/examples/trace.js
+++ b/packages/data-point/examples/trace.js
@@ -4,7 +4,7 @@ const mocks = require('./async-example.mocks')
 // mock request calls
 mocks()
 
-const { Model, Request } = DataPoint.entities
+const { Model, Request } = DataPoint
 
 const PersonRequest = Request('PersonRequest', {
   url: 'https://swapi.co/api/people/{value}/'
diff --git a/packages/data-point/lib/index.js b/packages/data-point/lib/index.js
index e0bc870..3779c38 100644
--- a/packages/data-point/lib/index.js
+++ b/packages/data-point/lib/index.js
@@ -1,14 +1,31 @@
 /* eslint global-require: 0 */
 
+const util = require('util')
+
 const core = require('./core')
 const helpers = require('./helpers')
-const entities = require('./entity-types').definitions
+const entityTypes = require('./entity-types').definitions
 const { createTypeCheckReducer } = require('./helpers/type-check-functions')
 
+const deprecatedEntitiesTypesAccess = util.deprecate(
+  () => entityTypes,
+  'DataPoint.entities is being deprecated, please access entity factories directly from DataPoint. (e.g. DataPoint.Model'
+)
+const deprecatedHelpersAccess = util.deprecate(
+  () => helpers.helpers,
+  'DataPoint.helpers is being deprecated, please access helper methods directly from DataPoint. (e.g. DataPoint.map'
+)
+
 module.exports = {
-  entities,
+  get entities () {
+    return deprecatedEntitiesTypesAccess()
+  },
+  get helpers () {
+    return deprecatedHelpersAccess()
+  },
+  ...entityTypes,
+  ...helpers.helpers,
   create: core.create,
-  helpers: helpers.helpers,
   createEntity: helpers.createEntity,
   resolveEntity: helpers.resolveEntity,
   entityFactories: helpers.entityFactories,


Test patch:
diff --git a/packages/data-point/lib/__snapshots__/index.test.js.snap b/packages/data-point/lib/__snapshots__/index.test.js.snap
index 3e2d26a..36143ee 100644
--- a/packages/data-point/lib/__snapshots__/index.test.js.snap
+++ b/packages/data-point/lib/__snapshots__/index.test.js.snap
@@ -2,6 +2,16 @@
 
 exports[`lib It should explicity expose set of methods 1`] = `
 Object {
+  "Collection": [Function],
+  "Control": [Function],
+  "Entry": [Function],
+  "Hash": [Function],
+  "Model": [Function],
+  "Reducer": [Function],
+  "Request": [Function],
+  "Schema": [Function],
+  "assign": [Function],
+  "constant": [Function],
   "create": [Function],
   "createEntity": [Function],
   "createReducer": [Function],
@@ -27,6 +37,8 @@ Object {
     "Request": [Function],
     "Schema": [Function],
   },
+  "filter": [Function],
+  "find": [Function],
   "helpers": Object {
     "assign": [Function],
     "constant": [Function],
@@ -38,8 +50,13 @@ Object {
     "pick": [Function],
     "withDefault": [Function],
   },
+  "map": [Function],
+  "omit": [Function],
+  "parallel": [Function],
+  "pick": [Function],
   "reducify": [Function],
   "reducifyAll": [Function],
   "resolveEntity": [Function],
+  "withDefault": [Function],
 }
 `;
diff --git a/packages/data-point/lib/reducer-types/reducer-helpers/reducer-constant/resolve.test.js b/packages/data-point/lib/reducer-types/reducer-helpers/reducer-constant/resolve.test.js
index ebf72d0..0c160ac 100644
--- a/packages/data-point/lib/reducer-types/reducer-helpers/reducer-constant/resolve.test.js
+++ b/packages/data-point/lib/reducer-types/reducer-helpers/reducer-constant/resolve.test.js
@@ -1,7 +1,7 @@
 /* eslint-env jest */
 
 const DataPoint = require('../../../index')
-const constant = DataPoint.helpers.constant
+const constant = DataPoint.constant
 
 const dataPoint = DataPoint.create()
 
diff --git a/packages/data-point/lib/reducer-types/reducer-helpers/reducer-parallel/resolve.test.js b/packages/data-point/lib/reducer-types/reducer-helpers/reducer-parallel/resolve.test.js
index 252e64b..79a2b7d 100644
--- a/packages/data-point/lib/reducer-types/reducer-helpers/reducer-parallel/resolve.test.js
+++ b/packages/data-point/lib/reducer-types/reducer-helpers/reducer-parallel/resolve.test.js
@@ -39,7 +39,7 @@ describe('ReducerOmit#resolve', () => {
         b: '$b'
       },
       ['$c', input => input + 2],
-      DataPoint.helpers.parallel(['$a', '$b', '$c'])
+      DataPoint.parallel(['$a', '$b', '$c'])
     ])
     return Resolve.resolve(manager, Reducer.resolve, accumulator, reducer).then(
       result => {
diff --git a/packages/data-point/lib/reducer-types/reducer-object/factory.test.js b/packages/data-point/lib/reducer-types/reducer-object/factory.test.js
index e3599f0..0e8f20e 100644
--- a/packages/data-point/lib/reducer-types/reducer-object/factory.test.js
+++ b/packages/data-point/lib/reducer-types/reducer-object/factory.test.js
@@ -2,7 +2,7 @@
 
 const factory = require('./factory')
 const createReducer = require('../index').create
-const constant = require('../..').helpers.constant
+const constant = require('../..').constant
 
 test('ReducerObject.factory#isType', () => {
   expect(factory.isType('$foo')).toBe(false)
diff --git a/packages/data-point/lib/reducer-types/reducer-object/resolve.test.js b/packages/data-point/lib/reducer-types/reducer-object/resolve.test.js
index 029b9cc..b83426c 100644
--- a/packages/data-point/lib/reducer-types/reducer-object/resolve.test.js
+++ b/packages/data-point/lib/reducer-types/reducer-object/resolve.test.js
@@ -6,7 +6,7 @@ const createReducer = require('../index').create
 const resolveReducer = require('../index').resolve
 const AccumulatorFactory = require('../../accumulator/factory')
 const FixtureStore = require('../../../test/utils/fixture-store')
-const constant = require('../..').helpers.constant
+const constant = require('../..').constant
 
 let dataPoint
 
diff --git a/packages/data-point/test/definitions/requests.js b/packages/data-point/test/definitions/requests.js
index ad594c8..4d74853 100644
--- a/packages/data-point/test/definitions/requests.js
+++ b/packages/data-point/test/definitions/requests.js
@@ -1,5 +1,5 @@
 const reducers = require('../utils/reducers')
-const { assign } = require('../../lib').helpers
+const { assign } = require('../../lib')
 
 module.exports = {
   'request:a0.1': {