[
  {
    "path": ".babelrc",
    "content": "{\n  \"presets\": [\n    [\n      \"env\",\n      {\n        \"targets\": {\n          \"browsers\": [\n            \"ie >= 11\"\n          ]\n        },\n        \"exclude\": [\"transform-async-to-generator\", \"transform-regenerator\"],\n        \"modules\": false,\n        \"loose\": true\n      }\n    ]\n  ],\n  \"plugins\": [\n    \"transform-object-rest-spread\"\n  ],\n  \"env\": {\n    \"commonjs\": {\n      \"presets\": [\n        [\n          \"env\",\n          {\n            \"loose\": true\n          }\n        ]\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": ".eslintrc",
    "content": "{\n  \"extends\": \"react-app\"\n}\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\n.idea\ncoverage\n\n.DS_Store\n.nvmrc\nnpm-debug.log\nyarn-error.log\n\neslint.json\njasmine.json\njasmine.*.json\n\nbin/*\n\n#*git*\n#.git*\n\n*.tar*\n*.gz*\n*dump*\n\n.~*\n\nlogs/*.log\n\n.coverdata\n.coverrun\nresults/\njsconfig.json\n.tern-project\n.vscode\n\ndist\nlib\nes\ncoverage\n_book\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"node\"\nscript:\n  - npm run lint\n  - npm run test:cov\nafter_success:\n  - npm run coveralls\ncache: yarn\n"
  },
  {
    "path": "CNAME",
    "content": "redux-arc.js.org\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-2016 Reselect Contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.html",
    "content": "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><style>body {\n  max-width: 980px;\n  border: 1px solid #ddd;\n  outline: 1300px solid #fff;\n  margin: 16px auto;\n}\n\nbody .markdown-body\n{\n  padding: 45px;\n}\n\n@font-face {\n  font-family: fontawesome-mini;\n  src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAzUABAAAAAAFNgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABbAAAABwAAAAcZMzaOEdERUYAAAGIAAAAHQAAACAAOQAET1MvMgAAAagAAAA+AAAAYHqhde9jbWFwAAAB6AAAAFIAAAFa4azkLWN2dCAAAAI8AAAAKAAAACgFgwioZnBnbQAAAmQAAAGxAAACZVO0L6dnYXNwAAAEGAAAAAgAAAAIAAAAEGdseWYAAAQgAAAFDgAACMz7eroHaGVhZAAACTAAAAAwAAAANgWEOEloaGVhAAAJYAAAAB0AAAAkDGEGa2htdHgAAAmAAAAAEwAAADBEgAAQbG9jYQAACZQAAAAaAAAAGgsICJBtYXhwAAAJsAAAACAAAAAgASgBD25hbWUAAAnQAAACZwAABOD4no+3cG9zdAAADDgAAABsAAAAmF+yXM9wcmVwAAAMpAAAAC4AAAAusPIrFAAAAAEAAAAAyYlvMQAAAADLVHQgAAAAAM/u9uZ4nGNgZGBg4ANiCQYQYGJgBEJuIGYB8xgABMMAPgAAAHicY2Bm42OcwMDKwMLSw2LMwMDQBqGZihmiwHycoKCyqJjB4YPDh4NsDP+BfNb3DIuAFCOSEgUGRgAKDgt4AAB4nGNgYGBmgGAZBkYGEAgB8hjBfBYGCyDNxcDBwMTA9MHhQ9SHrA8H//9nYACyQyFs/sP86/kX8HtB9UIBIxsDXICRCUgwMaACRoZhDwA3fxKSAAAAAAHyAHABJQB/AIEAdAFGAOsBIwC/ALgAxACGAGYAugBNACcA/wCIeJxdUbtOW0EQ3Q0PA4HE2CA52hSzmZDGe6EFCcTVjWJkO4XlCGk3cpGLcQEfQIFEDdqvGaChpEibBiEXSHxCPiESM2uIojQ7O7NzzpkzS8qRqnfpa89T5ySQwt0GzTb9Tki1swD3pOvrjYy0gwdabGb0ynX7/gsGm9GUO2oA5T1vKQ8ZTTuBWrSn/tH8Cob7/B/zOxi0NNP01DoJ6SEE5ptxS4PvGc26yw/6gtXhYjAwpJim4i4/plL+tzTnasuwtZHRvIMzEfnJNEBTa20Emv7UIdXzcRRLkMumsTaYmLL+JBPBhcl0VVO1zPjawV2ys+hggyrNgQfYw1Z5DB4ODyYU0rckyiwNEfZiq8QIEZMcCjnl3Mn+pED5SBLGvElKO+OGtQbGkdfAoDZPs/88m01tbx3C+FkcwXe/GUs6+MiG2hgRYjtiKYAJREJGVfmGGs+9LAbkUvvPQJSA5fGPf50ItO7YRDyXtXUOMVYIen7b3PLLirtWuc6LQndvqmqo0inN+17OvscDnh4Lw0FjwZvP+/5Kgfo8LK40aA4EQ3o3ev+iteqIq7wXPrIn07+xWgAAAAABAAH//wAPeJyFlctvG1UUh+/12DPN1B7P3JnYjj2Ox4/MuDHxJH5N3UdaEUQLqBIkfQQioJWQ6AMEQkIqsPGCPwA1otuWSmTBhjtps2ADWbJg3EpIXbGouqSbCraJw7kzNo2dRN1cnXN1ZvT7zuuiMEI7ncizyA0URofRBJpCdbQuIFShYY+GZRrxMDVtih5TwQPHtXDFFSIKoWIbuREBjLH27Ny4MsbVx+uOJThavebgVrNRLAiYx06rXsvhxLgWx9xpfHdrs/ekc2Pl2cpPCVEITQpwbj8VQhfXSq2m+Wxqaq2D73Kne5e3NjHqQNj3CRYlJlgUl/jRNP+2Gs2pNYRQiOnmUaQDqm30KqKiTTWPWjboxnTWpvgxjXo0KrtZXAHt7hwIz0YVcj88JnKlJKi3NPAwLyDwZudSmJSMMJFDYaOkaol6XtESx3Gt1VTytdZJ3DCLeaVhVnCBH1fycHTxFXwPX+l2e3d6H/TufGGmMTLTnbSJUdo00zuBswMO/nl3YLeL/wnu9/limCuD3vC54h5NBVz6Li414AI8Vx3iiosKcQXUbrvhFFiYb++HN4DaF4XzFW0fIN4XDWJ3a3XQoq9V8WiyRmdsatV9xUcHims1JloH0YUa090G3Tro3mC6c01f+YwCPquINr1PTaCP6rVTOOmf0GE2dBc7zWIhji3/5MchSuBHgDbU99RMWt3YUNMZMJmx92YP6NsHx/5/M1yvInpnkIOM3Z8fA3JQ2lW1RFC1KaBPDFXNAHYYvGy73aYZZZ3HifbeuiVZCpwA3oQBs0wGPYJbJfg60xrKEbKiNtTe1adwrpBRwlAuQ3q3VRaX0QmQ9a49BTSCuF1MLfQ6+tinOubRBZuWPNoMevGMT+V41KitO1is3D/tpMcq1JHZqDHGs8DoYGDkxJgKjHROeTCmhZvzPm9pod+ltKm4PN7Dyvvldlpsg8D+4AUJZ3F/JBstZz7cbFRxsaAGV6yX/dkcycWf8eS3QlQea+YLjdm3yrOnrhFpUyKVvFE4lpv4bO3Svx/6F/4xmiDu/RT5iI++lko18mY1oX+5UGKR6kmVjM/Zb76yfHtxy+h/SyQ0lLdpdKy/lWB6szatetQJ8nZ80A2Qt6ift6gJeavU3BO4gtxs/KCtNPVibCtYCWY3SIlSBPKXZALXiIR9oZeJ1AuMyxLpHIy/yO7vSiSE+kZvk0ihJ30HgHfzZtEMmvV58x6dtqns0XTAW7Vdm4HJ04OCp/crOO7rd9SGxQAE/mVA9xRN+kVSMRFF6S9JFGUtthkjBA5tFCWc2l4V43Ex9GmUP3SI37Jjmir9KqlaDJ4S4JB3vuM/jzyH1+8MuoZ+QGzfnvPoJb96cZlWjMcKLfgDwB7E634JTY+asjsPzS5CiVnEWY+KsrsIN5rn3mAPjqmQBxGjcGKB9f9ZxY3mYC2L85CJ2FXIxKKyHk+dg0FHbuEc7D5NzWUX32WxFcWNGRAbvwSx0RmIXVDuYySafluQBmzA/ssqJAMLnli+WIC90Gw4lm85wcp0qjArEDPJJV/sSx4P9ungTpgMw5gVC1XO4uULq0s3v1rqLi0vX/z65vlH50f8T/RHmSPTk5xxWBWOluMT6WiOy+tdvWxlV/XQb3o3c6Ssr+r6I708GsX9/nzp1tKFh0s3v7m4vAy/Hnb/KMOvc1wump6Il48K6mGDy02X9Yd65pa+nQIjk76lWxCkG8NBCP0HQS9IpAAAeJxjYGRgYGBhcCrq214Qz2/zlUGenQEEzr/77oug/zewFbB+AHI5GJhAogBwKQ0qeJxjYGRgYH3/P46BgZ0BBNgKGBgZUAEPAE/7At0AAAB4nGNngAB2IGYjhBsYBAAIYADVAAAAAAAAAAAAAFwAyAEeAaACCgKmAx4DggRmAAAAAQAAAAwAagAEAAAAAAACAAEAAgAWAAABAAChAAAAAHiclZI7bxQxFIWPd/JkUYQChEhIyAVKgdBMskm1QkKrRETpQiLRUczueB/K7HhlOxttg8LvoKPgP9DxFxANDR0tHRWi4NjrPIBEgh1p/dm+vufcawNYFWsQmP6e4jSyQB2fI9cwj++RE9wTjyPP4LYoI89iWbyLPIe6+Bh5Hs9rryMv4GbtW+RF3EhuRa7jbrIbeQkPkjdUETOLnL0Kip4FVvAhco1RXyMnSPEz8gzWxE7kWTwUp5HnsCLeR57HW/El8gJWa58iL+JO7UfkOh4l9yMv4UnyEtvQGGECgwF66MNBooF1bGCL1ELB/TYU+ZBRlvsKQ44Se6jQ4a7hef+fh72Crv25kp+8lNWGmeKoOI5jJLb1aGIGvb6TjfWNLdkqdFvJw4l1amjlXtXRZqRN7lSRylZZyhBqpVFWmTEXgWfUrpi/hZOQXdOd4rKuXOtEWT3k5IArPRzTUU5tHKjecZkTpnVbNOnt6jzN8240GD4xtikvZW56043rPMg/dS+dlOceXoR+WPbJ55Dsekq1lJpnypsMUsYOdCW30o103Ytu/lvh+5RWFLfBjm9/N8hJntPhvx92rnoE/kyHdGasGy754kw36vsVf/lFeBi+0COu+cfgQr42G3CRpeLoZ53gmfe3X6rcKt5oVxnptHR9JS8ehVUd5wvvahN2uqxOOpMXapibI5k7Zwbt4xBSaTfoKBufhAnO/uqNcfK8OTs0OQ6l7JIqFjDhYj5WcjevCnI/1DDiI8j4ndWb/5YzDZWh79yomWXeXj7Nnw70/2TIeFPTrlSh89k1ObOSRVZWZfgF0r/zJQB4nG2JUQuCQBCEd07TTg36fb2IyBaLd3vWaUh/vmSJnvpgmG8YcmS8X3Shf3R7QA4OBUocUKHGER5NNbOOEvwc1txnuWkTRb/aPjimJ5vXabI+3VfOiyS15UWvyezM2xiGOPyuMohOH8O8JiO4Af+FsAGNAEuwCFBYsQEBjlmxRgYrWCGwEFlLsBRSWCGwgFkdsAYrXFhZsBQrAAA=) format('woff');\n}\n\n@font-face {\n  font-family: octicons-anchor;\n  src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==) format('woff');\n}\n\n.markdown-body {\n  font-family: sans-serif;\n  -ms-text-size-adjust: 100%;\n  -webkit-text-size-adjust: 100%;\n  color: #333333;\n  overflow: hidden;\n  font-family: \"Helvetica Neue\", Helvetica, \"Segoe UI\", Arial, freesans, sans-serif;\n  font-size: 16px;\n  line-height: 1.6;\n  word-wrap: break-word;\n}\n\n.markdown-body a {\n  background: transparent;\n}\n\n.markdown-body a:active,\n.markdown-body a:hover {\n  outline: 0;\n}\n\n.markdown-body b,\n.markdown-body strong {\n  font-weight: bold;\n}\n\n.markdown-body mark {\n  background: #ff0;\n  color: #000;\n  font-style: italic;\n  font-weight: bold;\n}\n\n.markdown-body sub,\n.markdown-body sup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n.markdown-body sup {\n  top: -0.5em;\n}\n.markdown-body sub {\n  bottom: -0.25em;\n}\n\n.markdown-body h1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\n\n.markdown-body img {\n  border: 0;\n}\n\n.markdown-body hr {\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  height: 0;\n}\n\n.markdown-body pre {\n  overflow: auto;\n}\n\n.markdown-body code,\n.markdown-body kbd,\n.markdown-body pre,\n.markdown-body samp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\n\n.markdown-body input {\n  color: inherit;\n  font: inherit;\n  margin: 0;\n}\n\n.markdown-body html input[disabled] {\n  cursor: default;\n}\n\n.markdown-body input {\n  line-height: normal;\n}\n\n.markdown-body input[type=\"checkbox\"] {\n  box-sizing: border-box;\n  padding: 0;\n}\n\n.markdown-body table {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\n.markdown-body td,\n.markdown-body th {\n  padding: 0;\n}\n\n.markdown-body .codehilitetable {\n  border: 0;\n  border-spacing: 0;\n}\n\n.markdown-body .codehilitetable tr {\n  border: 0;\n}\n\n.markdown-body .codehilitetable pre,\n.markdown-body .codehilitetable div.codehilite {\n  margin: 0;\n}\n\n.markdown-body .linenos,\n.markdown-body .code,\n.markdown-body .codehilitetable td {\n  border: 0;\n  padding: 0;\n}\n\n.markdown-body td:not(.linenos) .linenodiv {\n  padding: 0 !important;\n}\n\n.markdown-body .code {\n  width: 100%;\n}\n\n.markdown-body .linenos div pre,\n.markdown-body .linenodiv pre,\n.markdown-body .linenodiv {\n  border: 0;\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n  -webkit-border-top-left-radius: 3px;\n  -webkit-border-bottom-left-radius: 3px;\n  -moz-border-radius-topleft: 3px;\n  -moz-border-radius-bottomleft: 3px;\n  border-top-left-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n\n.markdown-body .code div pre,\n.markdown-body .code div {\n  border: 0;\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n  -webkit-border-top-right-radius: 3px;\n  -webkit-border-bottom-right-radius: 3px;\n  -moz-border-radius-topright: 3px;\n  -moz-border-radius-bottomright: 3px;\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n\n.markdown-body * {\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\n\n.markdown-body input {\n  font: 13px Helvetica, arial, freesans, clean, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n  line-height: 1.4;\n}\n\n.markdown-body a {\n  color: #4183c4;\n  text-decoration: none;\n}\n\n.markdown-body a:hover,\n.markdown-body a:focus,\n.markdown-body a:active {\n  text-decoration: underline;\n}\n\n.markdown-body hr {\n  height: 0;\n  margin: 15px 0;\n  overflow: hidden;\n  background: transparent;\n  border: 0;\n  border-bottom: 1px solid #ddd;\n}\n\n.markdown-body hr:before,\n.markdown-body hr:after {\n  display: table;\n  content: \" \";\n}\n\n.markdown-body hr:after {\n  clear: both;\n}\n\n.markdown-body h1,\n.markdown-body h2,\n.markdown-body h3,\n.markdown-body h4,\n.markdown-body h5,\n.markdown-body h6 {\n  margin-top: 15px;\n  margin-bottom: 15px;\n  line-height: 1.1;\n}\n\n.markdown-body h1 {\n  font-size: 30px;\n}\n\n.markdown-body h2 {\n  font-size: 21px;\n}\n\n.markdown-body h3 {\n  font-size: 16px;\n}\n\n.markdown-body h4 {\n  font-size: 14px;\n}\n\n.markdown-body h5 {\n  font-size: 12px;\n}\n\n.markdown-body h6 {\n  font-size: 11px;\n}\n\n.markdown-body blockquote {\n  margin: 0;\n}\n\n.markdown-body ul,\n.markdown-body ol {\n  padding: 0;\n  margin-top: 0;\n  margin-bottom: 0;\n}\n\n.markdown-body ol ol,\n.markdown-body ul ol {\n  list-style-type: lower-roman;\n}\n\n.markdown-body ul ul ol,\n.markdown-body ul ol ol,\n.markdown-body ol ul ol,\n.markdown-body ol ol ol {\n  list-style-type: lower-alpha;\n}\n\n.markdown-body dd {\n  margin-left: 0;\n}\n\n.markdown-body code,\n.markdown-body pre,\n.markdown-body samp {\n  font-family: Consolas, \"Liberation Mono\", Menlo, Courier, monospace;\n  font-size: 12px;\n}\n\n.markdown-body pre {\n  margin-top: 0;\n  margin-bottom: 0;\n}\n\n.markdown-body kbd {\n  background-color: #e7e7e7;\n  background-image: -moz-linear-gradient(#fefefe, #e7e7e7);\n  background-image: -webkit-linear-gradient(#fefefe, #e7e7e7);\n  background-image: linear-gradient(#fefefe, #e7e7e7);\n  background-repeat: repeat-x;\n  border-radius: 2px;\n  border: 1px solid #cfcfcf;\n  color: #000;\n  padding: 3px 5px;\n  line-height: 10px;\n  font: 11px Consolas, \"Liberation Mono\", Menlo, Courier, monospace;\n  display: inline-block;\n}\n\n.markdown-body>*:first-child {\n  margin-top: 0 !important;\n}\n\n.markdown-body>*:last-child {\n  margin-bottom: 0 !important;\n}\n\n.markdown-body .headeranchor-link {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  display: block;\n  padding-right: 6px;\n  padding-left: 30px;\n  margin-left: -30px;\n}\n\n.markdown-body .headeranchor-link:focus {\n  outline: none;\n}\n\n.markdown-body h1,\n.markdown-body h2,\n.markdown-body h3,\n.markdown-body h4,\n.markdown-body h5,\n.markdown-body h6 {\n  position: relative;\n  margin-top: 1em;\n  margin-bottom: 16px;\n  font-weight: bold;\n  line-height: 1.4;\n}\n\n.markdown-body h1 .headeranchor,\n.markdown-body h2 .headeranchor,\n.markdown-body h3 .headeranchor,\n.markdown-body h4 .headeranchor,\n.markdown-body h5 .headeranchor,\n.markdown-body h6 .headeranchor {\n  display: none;\n  color: #000;\n  vertical-align: middle;\n}\n\n.markdown-body h1:hover .headeranchor-link,\n.markdown-body h2:hover .headeranchor-link,\n.markdown-body h3:hover .headeranchor-link,\n.markdown-body h4:hover .headeranchor-link,\n.markdown-body h5:hover .headeranchor-link,\n.markdown-body h6:hover .headeranchor-link {\n  height: 1em;\n  padding-left: 8px;\n  margin-left: -30px;\n  line-height: 1;\n  text-decoration: none;\n}\n\n.markdown-body h1:hover .headeranchor-link .headeranchor,\n.markdown-body h2:hover .headeranchor-link .headeranchor,\n.markdown-body h3:hover .headeranchor-link .headeranchor,\n.markdown-body h4:hover .headeranchor-link .headeranchor,\n.markdown-body h5:hover .headeranchor-link .headeranchor,\n.markdown-body h6:hover .headeranchor-link .headeranchor {\n  display: inline-block;\n}\n\n.markdown-body h1 {\n  padding-bottom: 0.3em;\n  font-size: 2.25em;\n  line-height: 1.2;\n  border-bottom: 1px solid #eee;\n}\n\n.markdown-body h2 {\n  padding-bottom: 0.3em;\n  font-size: 1.75em;\n  line-height: 1.225;\n  border-bottom: 1px solid #eee;\n}\n\n.markdown-body h3 {\n  font-size: 1.5em;\n  line-height: 1.43;\n}\n\n.markdown-body h4 {\n  font-size: 1.25em;\n}\n\n.markdown-body h5 {\n  font-size: 1em;\n}\n\n.markdown-body h6 {\n  font-size: 1em;\n  color: #777;\n}\n\n.markdown-body p,\n.markdown-body blockquote,\n.markdown-body ul,\n.markdown-body ol,\n.markdown-body dl,\n.markdown-body table,\n.markdown-body pre,\n.markdown-body .admonition {\n  margin-top: 0;\n  margin-bottom: 16px;\n}\n\n.markdown-body hr {\n  height: 4px;\n  padding: 0;\n  margin: 16px 0;\n  background-color: #e7e7e7;\n  border: 0 none;\n}\n\n.markdown-body ul,\n.markdown-body ol {\n  padding-left: 2em;\n}\n\n.markdown-body ul ul,\n.markdown-body ul ol,\n.markdown-body ol ol,\n.markdown-body ol ul {\n  margin-top: 0;\n  margin-bottom: 0;\n}\n\n.markdown-body li>p {\n  margin-top: 16px;\n}\n\n.markdown-body dl {\n  padding: 0;\n}\n\n.markdown-body dl dt {\n  padding: 0;\n  margin-top: 16px;\n  font-size: 1em;\n  font-style: italic;\n  font-weight: bold;\n}\n\n.markdown-body dl dd {\n  padding: 0 16px;\n  margin-bottom: 16px;\n}\n\n.markdown-body blockquote {\n  padding: 0 15px;\n  color: #777;\n  border-left: 4px solid #ddd;\n}\n\n.markdown-body blockquote>:first-child {\n  margin-top: 0;\n}\n\n.markdown-body blockquote>:last-child {\n  margin-bottom: 0;\n}\n\n.markdown-body table {\n  display: block;\n  width: 100%;\n  overflow: auto;\n  word-break: normal;\n  word-break: keep-all;\n}\n\n.markdown-body table th {\n  font-weight: bold;\n}\n\n.markdown-body table th,\n.markdown-body table td {\n  padding: 6px 13px;\n  border: 1px solid #ddd;\n}\n\n.markdown-body table tr {\n  background-color: #fff;\n  border-top: 1px solid #ccc;\n}\n\n.markdown-body table tr:nth-child(2n) {\n  background-color: #f8f8f8;\n}\n\n.markdown-body img {\n  max-width: 100%;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\n\n.markdown-body code,\n.markdown-body samp {\n  padding: 0;\n  padding-top: 0.2em;\n  padding-bottom: 0.2em;\n  margin: 0;\n  font-size: 85%;\n  background-color: rgba(0,0,0,0.04);\n  border-radius: 3px;\n}\n\n.markdown-body code:before,\n.markdown-body code:after {\n  letter-spacing: -0.2em;\n  content: \"\\00a0\";\n}\n\n.markdown-body pre>code {\n  padding: 0;\n  margin: 0;\n  font-size: 100%;\n  word-break: normal;\n  white-space: pre;\n  background: transparent;\n  border: 0;\n}\n\n.markdown-body .codehilite {\n  margin-bottom: 16px;\n}\n\n.markdown-body .codehilite pre,\n.markdown-body pre {\n  padding: 16px;\n  overflow: auto;\n  font-size: 85%;\n  line-height: 1.45;\n  background-color: #f7f7f7;\n  border-radius: 3px;\n}\n\n.markdown-body .codehilite pre {\n  margin-bottom: 0;\n  word-break: normal;\n}\n\n.markdown-body pre {\n  word-wrap: normal;\n}\n\n.markdown-body pre code {\n  display: inline;\n  max-width: initial;\n  padding: 0;\n  margin: 0;\n  overflow: initial;\n  line-height: inherit;\n  word-wrap: normal;\n  background-color: transparent;\n  border: 0;\n}\n\n.markdown-body pre code:before,\n.markdown-body pre code:after {\n  content: normal;\n}\n\n/* Admonition */\n.markdown-body .admonition {\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  position: relative;\n  border-radius: 3px;\n  border: 1px solid #e0e0e0;\n  border-left: 6px solid #333;\n  padding: 10px 10px 10px 30px;\n}\n\n.markdown-body .admonition table {\n  color: #333;\n}\n\n.markdown-body .admonition p {\n  padding: 0;\n}\n\n.markdown-body .admonition-title {\n  font-weight: bold;\n  margin: 0;\n}\n\n.markdown-body .admonition>.admonition-title {\n  color: #333;\n}\n\n.markdown-body .attention>.admonition-title {\n  color: #a6d796;\n}\n\n.markdown-body .caution>.admonition-title {\n  color: #d7a796;\n}\n\n.markdown-body .hint>.admonition-title {\n  color: #96c6d7;\n}\n\n.markdown-body .danger>.admonition-title {\n  color: #c25f77;\n}\n\n.markdown-body .question>.admonition-title {\n  color: #96a6d7;\n}\n\n.markdown-body .note>.admonition-title {\n  color: #d7c896;\n}\n\n.markdown-body .admonition:before,\n.markdown-body .attention:before,\n.markdown-body .caution:before,\n.markdown-body .hint:before,\n.markdown-body .danger:before,\n.markdown-body .question:before,\n.markdown-body .note:before {\n  font: normal normal 16px fontawesome-mini;\n  -moz-osx-font-smoothing: grayscale;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  line-height: 1.5;\n  color: #333;\n  position: absolute;\n  left: 0;\n  top: 0;\n  padding-top: 10px;\n  padding-left: 10px;\n}\n\n.markdown-body .admonition:before {\n  content: \"\\f056\\00a0\";\n  color: 333;\n}\n\n.markdown-body .attention:before {\n  content: \"\\f058\\00a0\";\n  color: #a6d796;\n}\n\n.markdown-body .caution:before {\n  content: \"\\f06a\\00a0\";\n  color: #d7a796;\n}\n\n.markdown-body .hint:before {\n  content: \"\\f05a\\00a0\";\n  color: #96c6d7;\n}\n\n.markdown-body .danger:before {\n  content: \"\\f057\\00a0\";\n  color: #c25f77;\n}\n\n.markdown-body .question:before {\n  content: \"\\f059\\00a0\";\n  color: #96a6d7;\n}\n\n.markdown-body .note:before {\n  content: \"\\f040\\00a0\";\n  color: #d7c896;\n}\n\n.markdown-body .admonition::after {\n  content: normal;\n}\n\n.markdown-body .attention {\n  border-left: 6px solid #a6d796;\n}\n\n.markdown-body .caution {\n  border-left: 6px solid #d7a796;\n}\n\n.markdown-body .hint {\n  border-left: 6px solid #96c6d7;\n}\n\n.markdown-body .danger {\n  border-left: 6px solid #c25f77;\n}\n\n.markdown-body .question {\n  border-left: 6px solid #96a6d7;\n}\n\n.markdown-body .note {\n  border-left: 6px solid #d7c896;\n}\n\n.markdown-body .admonition>*:first-child {\n  margin-top: 0 !important;\n}\n\n.markdown-body .admonition>*:last-child {\n  margin-bottom: 0 !important;\n}\n\n/* progress bar*/\n.markdown-body .progress {\n  display: block;\n  width: 300px;\n  margin: 10px 0;\n  height: 24px;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n  background-color: #ededed;\n  position: relative;\n  box-shadow: inset -1px 1px 3px rgba(0, 0, 0, .1);\n}\n\n.markdown-body .progress-label {\n  position: absolute;\n  text-align: center;\n  font-weight: bold;\n  width: 100%; margin: 0;\n  line-height: 24px;\n  color: #333;\n  text-shadow: 1px 1px 0 #fefefe, -1px -1px 0 #fefefe, -1px 1px 0 #fefefe, 1px -1px 0 #fefefe, 0 1px 0 #fefefe, 0 -1px 0 #fefefe, 1px 0 0 #fefefe, -1px 0 0 #fefefe, 1px 1px 2px #000;\n  -webkit-font-smoothing: antialiased !important;\n  white-space: nowrap;\n  overflow: hidden;\n}\n\n.markdown-body .progress-bar {\n  height: 24px;\n  float: left;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n  background-color: #96c6d7;\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), inset 0 -1px 0 rgba(0, 0, 0, .1);\n  background-size: 30px 30px;\n  background-image: -webkit-linear-gradient(\n    135deg, rgba(255, 255, 255, .4) 27%,\n    transparent 27%,\n    transparent 52%, rgba(255, 255, 255, .4) 52%,\n    rgba(255, 255, 255, .4) 77%,\n    transparent 77%, transparent\n  );\n  background-image: -moz-linear-gradient(\n    135deg,\n    rgba(255, 255, 255, .4) 27%, transparent 27%,\n    transparent 52%, rgba(255, 255, 255, .4) 52%,\n    rgba(255, 255, 255, .4) 77%, transparent 77%,\n    transparent\n  );\n  background-image: -ms-linear-gradient(\n    135deg,\n    rgba(255, 255, 255, .4) 27%, transparent 27%,\n    transparent 52%, rgba(255, 255, 255, .4) 52%,\n    rgba(255, 255, 255, .4) 77%, transparent 77%,\n    transparent\n  );\n  background-image: -o-linear-gradient(\n    135deg,\n    rgba(255, 255, 255, .4) 27%, transparent 27%,\n    transparent 52%, rgba(255, 255, 255, .4) 52%,\n    rgba(255, 255, 255, .4) 77%, transparent 77%,\n    transparent\n  );\n  background-image: linear-gradient(\n    135deg,\n    rgba(255, 255, 255, .4) 27%, transparent 27%,\n    transparent 52%, rgba(255, 255, 255, .4) 52%,\n    rgba(255, 255, 255, .4) 77%, transparent 77%,\n    transparent\n  );\n}\n\n.markdown-body .progress-100plus .progress-bar {\n  background-color: #a6d796;\n}\n\n.markdown-body .progress-80plus .progress-bar {\n  background-color: #c6d796;\n}\n\n.markdown-body .progress-60plus .progress-bar {\n  background-color: #d7c896;\n}\n\n.markdown-body .progress-40plus .progress-bar {\n  background-color: #d7a796;\n}\n\n.markdown-body .progress-20plus .progress-bar {\n  background-color: #d796a6;\n}\n\n.markdown-body .progress-0plus .progress-bar {\n  background-color: #c25f77;\n}\n\n.markdown-body .candystripe-animate .progress-bar{\n  -webkit-animation: animate-stripes 3s linear infinite;\n  -moz-animation: animate-stripes 3s linear infinite;\n  animation: animate-stripes 3s linear infinite;\n}\n\n@-webkit-keyframes animate-stripes {\n  0% {\n    background-position: 0 0;\n  }\n\n  100% {\n    background-position: 60px 0;\n  }\n}\n\n@-moz-keyframes animate-stripes {\n  0% {\n    background-position: 0 0;\n  }\n\n  100% {\n    background-position: 60px 0;\n  }\n}\n\n@keyframes animate-stripes {\n  0% {\n    background-position: 0 0;\n  }\n\n  100% {\n    background-position: 60px 0;\n  }\n}\n\n.markdown-body .gloss .progress-bar {\n  box-shadow:\n    inset 0 4px 12px rgba(255, 255, 255, .7),\n    inset 0 -12px 0 rgba(0, 0, 0, .05);\n}\n\n/* Multimarkdown Critic Blocks */\n.markdown-body .critic_mark {\n  background: #ff0;\n}\n\n.markdown-body .critic_delete {\n  color: #c82829;\n  text-decoration: line-through;\n}\n\n.markdown-body .critic_insert {\n  color: #718c00 ;\n  text-decoration: underline;\n}\n\n.markdown-body .critic_comment {\n  color: #8e908c;\n  font-style: italic;\n}\n\n.markdown-body .headeranchor {\n  font: normal normal 16px octicons-anchor;\n  line-height: 1;\n  display: inline-block;\n  text-decoration: none;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n\n.headeranchor:before {\n  content: '\\f05c';\n}\n\n.markdown-body .task-list-item {\n  list-style-type: none;\n}\n\n.markdown-body .task-list-item+.task-list-item {\n  margin-top: 3px;\n}\n\n.markdown-body .task-list-item input {\n  margin: 0 4px 0.25em -20px;\n  vertical-align: middle;\n}\n\n/* Media */\n@media only screen and (min-width: 480px) {\n  .markdown-body {\n    font-size:14px;\n  }\n}\n\n@media only screen and (min-width: 768px) {\n  .markdown-body {\n    font-size:16px;\n  }\n}\n\n@media print {\n  .markdown-body * {\n    background: transparent !important;\n    color: black !important;\n    filter:none !important;\n    -ms-filter: none !important;\n  }\n\n  .markdown-body {\n    font-size:12pt;\n    max-width:100%;\n    outline:none;\n    border: 0;\n  }\n\n  .markdown-body a,\n  .markdown-body a:visited {\n    text-decoration: underline;\n  }\n\n  .markdown-body .headeranchor-link {\n    display: none;\n  }\n\n  .markdown-body a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n\n  .markdown-body abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n\n  .markdown-body .ir a:after,\n  .markdown-body a[href^=\"javascript:\"]:after,\n  .markdown-body a[href^=\"#\"]:after {\n    content: \"\";\n  }\n\n  .markdown-body pre {\n    white-space: pre;\n    white-space: pre-wrap;\n    word-wrap: break-word;\n  }\n\n  .markdown-body pre,\n  .markdown-body blockquote {\n    border: 1px solid #999;\n    padding-right: 1em;\n    page-break-inside: avoid;\n  }\n\n  .markdown-body .progress,\n  .markdown-body .progress-bar {\n    -moz-box-shadow: none;\n    -webkit-box-shadow: none;\n    box-shadow: none;\n  }\n\n  .markdown-body .progress {\n    border: 1px solid #ddd;\n  }\n\n  .markdown-body .progress-bar {\n    height: 22px;\n    border-right: 1px solid #ddd;\n  }\n\n  .markdown-body tr,\n  .markdown-body img {\n    page-break-inside: avoid;\n  }\n\n  .markdown-body img {\n    max-width: 100% !important;\n  }\n\n  .markdown-body p,\n  .markdown-body h2,\n  .markdown-body h3 {\n    orphans: 3;\n    widows: 3;\n  }\n\n  .markdown-body h2,\n  .markdown-body h3 {\n    page-break-after: avoid;\n  }\n}\n</style><title>README</title></head><body><article class=\"markdown-body\"><p><img src=\"https://github.com/viniciusdacal/redux-arc/blob/master/arc-64.png?raw=true\" height=\"64\" /></p>\n<p>Create scalable, no-boilerplate redux Apps!</p>\n<p>Arc is an abstraction layer to help you reduce boilerplate on redux-apps and also, organize better your code. Additionally, it has utilities to handle async requests.</p>\n<p><a href=\"https://travis-ci.org/viniciusdacal/redux-arc\"><img alt=\"build status\" src=\"https://img.shields.io/travis/viniciusdacal/redux-arc/master.svg?style=flat-square\" /></a> <a href=\"https://www.npmjs.com/package/redux-arc\"><img alt=\"npm version\" src=\"https://img.shields.io/npm/v/redux-arc.svg?style=flat-square\" /></a><br />\n<a href=\"https://coveralls.io/github/viniciusdacal/redux-arc?branch=master\"><img alt=\"Coverage Status\" src=\"https://coveralls.io/repos/github/viniciusdacal/redux-arc/badge.svg?branch=master\" /></a></p>\n<h2 id=\"why\"><a name=\"user-content-why\" href=\"#why\" class=\"headeranchor-link\" aria-hidden=\"true\"><span class=\"headeranchor\"></span></a>Why</h2>\n<p>Redux is awesome! But people often complain about how much boilerplate they have to write when using it. Part of this problem, is because they feel unproductive defining constants, action creators and big reducers, but also because they don&rsquo;t have a clear idea on how to organize their project, or even how to proper handle async requests. This project, intends to help on all that aspects!</p>\n<p>We don&rsquo;t intend to recreate the wheel, instead, we tried to use what the community are used with, and build up some approaches together in order to clarify the things about the project architecture, code splitting and the things around actions.</p>\n<h2 id=\"creators-and-types-are-generated-by-a-config\"><a name=\"user-content-creators-and-types-are-generated-by-a-config\" href=\"#creators-and-types-are-generated-by-a-config\" class=\"headeranchor-link\" aria-hidden=\"true\"><span class=\"headeranchor\"></span></a>Creators and types are generated by a config</h2>\n<pre><code class=\"js\">  // actions.js\n  import { createActions } from 'redux-arc';\n\n  export { types, creators } = createActions('jedi', {\n    add: null,\n  });\n</code></pre>\n\n<h2 id=\"create-reducers-using-createreducers-and-types\"><a name=\"user-content-create-reducers-using-createreducers-and-types\" href=\"#create-reducers-using-createreducers-and-types\" class=\"headeranchor-link\" aria-hidden=\"true\"><span class=\"headeranchor\"></span></a>Create reducers using createReducers and types:</h2>\n<pre><code class=\"js\">  import { createReducers } from 'redux-arc';\n  import { types } from './actions';\n\n  const INITIAL_STATE = [];\n  const HANDLERS = {\n    [types.ADD]: (state, action) =&gt; [...state, action.payload]\n  };\n\n  export default createReducers(INITIAL_STATE, HANDLERS);\n</code></pre>\n\n<h2 id=\"call-the-creators-providing-payload-and-meta\"><a name=\"user-content-call-the-creators-providing-payload-and-meta\" href=\"#call-the-creators-providing-payload-and-meta\" class=\"headeranchor-link\" aria-hidden=\"true\"><span class=\"headeranchor\"></span></a>Call the creators providing payload and meta</h2>\n<pre><code class=\"js\">  import { creators } from './actions';\n\n  const payload = {\n    name: 'Luke',\n    master: 'Yoda',\n  };\n  const meta = { foo: 'bar' };\n\n  dispatch(creators.add(payload, meta))\n</code></pre>\n\n<h2 id=\"create-async-actions\"><a name=\"user-content-create-async-actions\" href=\"#create-async-actions\" class=\"headeranchor-link\" aria-hidden=\"true\"><span class=\"headeranchor\"></span></a>Create Async Actions</h2>\n<pre><code class=\"js\">  import { createActions } from 'redux-arc';\n\n  export { types, creators } = createActions('jedi', {\n    add: { url: '/api/jedi' method: 'post'},\n  });\n\n  dispatch(creators.add(payload, meta));\n\n  types.ADD.REQUEST // JEDI_ADD_REQUEST\n  types.ADD.RESPONSE // JEDI_ADD_RESPONSE\n</code></pre>\n\n<blockquote>\n<p>createActions creates both, regular and async actions. Async types has REQUEST and RESPONSE type, respectively to when a request starts and when it finishes.</p>\n</blockquote>\n<h1 id=\"getting-started\"><a name=\"user-content-getting-started\" href=\"#getting-started\" class=\"headeranchor-link\" aria-hidden=\"true\"><span class=\"headeranchor\"></span></a>Getting started</h1>\n<p><pre><code class=\"bash\">yarn add redux-arc\n</code></pre><br />\nor</p>\n<pre><code class=\"bash\">npm i --save redux-arc\n</code></pre>\n\n<p>To understand this docs, you should have a good understand of redux: what are Action creators, what are reducers, middlewares and also, what is a Flux Standard Action. So please, if you need a recap on those concepts, read the links bellow:</p>\n<p><a href=\"https://redux.js.org/\">Redux Docs</a><br />\n<a href=\"https://github.com/acdlite/flux-standard-action\">Flux Standard Action</a></p>\n<h1 id=\"action-creators-and-types\"><a name=\"user-content-action-creators-and-types\" href=\"#action-creators-and-types\" class=\"headeranchor-link\" aria-hidden=\"true\"><span class=\"headeranchor\"></span></a>Action creators and Types</h1>\n<p>When you have to create a new action on redux, the first 2 steps you usually do is defining a <strong>const</strong> to you <em>action type</em> and then defining an <em>action creator</em>.</p>\n<pre><code class=\"js\">const NEW_JEDI = 'NEW_JEDI';\n\nconst newJedi = (payload) =&gt; ({\n  type: NEW_JEDI,\n  payload,\n});\n</code></pre>\n\n<p>The above code is fine, but the problem is, you have dozens or hundreds of action in an application, and you are always writing the same code. Also, if you are not strict on code review, you end up having situations where your action type has a name different from your action creator:</p>\n<pre><code class=\"js\">const NEW_JEDI = 'NEW_JEDI';\n\nconst addJedi = (payload) =&gt; ({\n  type: NEW_JEDI,\n  payload,\n});\n</code></pre>\n\n<p>Thinking in the above issues, Arc has a <code>createAction</code> function, that you use to define your actions and it generates the types and action creators automatically for you. Take a look:</p>\n<pre><code class=\"js\">  import { createActions } from 'redux-arc';\n\n  const { types, creators } = createActions('yourNamespace', {\n    newJedi: null,\n  });\n\n  types.newJedi // YOUR_NAMESPACE_NEW_JEDI\n\n  const payload = {\n    master: 'Yoda',\n    name: 'Luke',\n  };\n\n  creators.newJedi(payload);\n  /*\n  {\n    type: 'YOUR_NAMESPACE_NEW_JEDI',\n    payload: {\n      master: 'Yoda',\n      name: 'Luke',\n    }\n  }\n  */\n</code></pre>\n\n<p>The <code>createActions</code> method, expects a namespace as its first argument, this will be uppercased and will serve as a prefix for the actions. As the second parameter, we need to provide a config object, which the key is the action name and the value is an object with default values for <strong>payload</strong> and <strong>meta</strong>, or <code>null</code> if you don&rsquo;t want to provide defaults. Then, it will return <strong>creators</strong> and <strong>types</strong>.</p>\n<p>Both creators and types are objects, the first one contains the action creators for the actions you defined. As in the case above we defined an action newJedi, then we have a creator at <code>creators.newJedi</code>.</p>\n<p>Creators accepts until three arguments:<br />\n - payload: could be of any type. Will become the <code>action.payload</code><br />\n - meta: could be of any type. Will become the <code>action.meta</code><br />\n - error: boolean. Indicates if the action has an error or not. You can omit it if the action has no error.</p>\n<blockquote>\n<p>The api was designed following the flux-standard-action concepts. It can be strict about how your action should look like, but this will help you creating better actions. Also, now you can be sure that the first parameter you provide to the action creator, will become the action.payload.</p>\n</blockquote>\n<p>The types is an object that contains strings. Its keys are the action names, but different from the creators, here they are uppercased:</p>\n<pre><code class=\"js\">  types.NEW_JEDI\n</code></pre>\n\n<p>Also, when you do a console.log to see its content, you can see that we prefix the actions with the namespace you provided:</p>\n<pre><code class=\"js\">  const { types } = createActions('yourNamespace', {\n    newJedi: null,\n  });\n\n  types.NEW_JEDI // -&gt; YOUR_NAMESPACE_NEW_JEDI\n\n</code></pre>\n\n<blockquote>\n<p>We decided to have the namespace, to not stop you from having actions with the same name in different modules. Don&rsquo;t worry, you will be able to differ them easily when using redux-dev-tools, just remember to provide unique namespaces.</p>\n</blockquote>\n<h1 id=\"async-actions\"><a name=\"user-content-async-actions\" href=\"#async-actions\" class=\"headeranchor-link\" aria-hidden=\"true\"><span class=\"headeranchor\"></span></a>Async Actions</h1>\n<p>Originally, Arc was created to be an abstraction layer to handle async request in Redux. So, it has all you need about that. The api to generate async actions and types is the same, you only need to provide some additional params in the action config object. Take a look below:</p>\n<pre><code class=\"js\">  import { createApiActions } from 'redux-arc';\n\n  const { creators, types } = createActions('todo', {\n    list:   { url: 'api/todo',     method: 'get'  },\n    read:   { url: 'api/todo/:id', method: 'get'  },\n    create: { url: 'api/todo',     method: 'post' },\n    update: { url: 'api/todo/:id', method: 'put'  },\n  });\n</code></pre>\n\n<p>Above are defined three actions: <code>list</code>, <code>read</code>, <code>create</code>.</p>\n<p>Two params are required for a async action config, <code>url</code> and <code>method</code>.<br />\n - <strong>url</strong>: You can define any url you want and it also accepts dynamic params, as you can see in the <code>read</code> action. We defined a dynamic param <strong>id</strong>, inserting <code>:id</code><br />\n - <strong>method</strong>: Generally speaking, any http method your request lib supports. This will be used only by you in the asyncMiddleware that you will configure.</p>\n<h3 id=\"async-creators-and-async-types\"><a name=\"user-content-async-creators-and-async-types\" href=\"#async-creators-and-async-types\" class=\"headeranchor-link\" aria-hidden=\"true\"><span class=\"headeranchor\"></span></a>Async Creators and Async Types</h3>\n<p>An async creator is very similar to a simple creator. It accepts <strong>payload</strong> and <strong>meta</strong> as arguments. They will further become the <code>action.payload</code> and <code>action.meta</code>, as in a regular creator. The difference here, is that the meta, should be an object, and its values will be used to parse dynamic urls. Considering that, the creator <strong>read</strong> should be used like that:</p>\n<pre><code class=\"js\">  const payload = null;\n  const meta = { id: '123' };\n  creators.read(payload, meta);\n</code></pre>\n\n<p>With the above code, the final url to your read request, would be <code>api/todo/123</code></p>\n<p>The async types differ a little bit from the regular ones as well. First, as a api call has two moments (request and response), we need two different types to use inside our reducers. Considering that, Arc returns an object for each type, containing a <code>REQUEST</code> and a <code>RESPONSE</code> key with the respective types:</p>\n<pre><code class=\"js\">  types.READ.REQUEST == 'TODO_READ_REQUEST';\n  types.READ.RESPONSE == 'TODO_READ_RESPONSE';\n</code></pre>\n\n<h3 id=\"async-middleware\"><a name=\"user-content-async-middleware\" href=\"#async-middleware\" class=\"headeranchor-link\" aria-hidden=\"true\"><span class=\"headeranchor\"></span></a>Async Middleware</h3>\n<p>Arc doesn&rsquo;t intend to be a request lib, so, you need to tell it how you want to make your requests, and you do that by configuring the asyncMiddleware.</p>\n<p>It&rsquo;s quite simple, take a look below in an example using axios:</p>\n<pre><code class=\"js\">import { createAsyncMiddleware } from 'redux-arc';\nimport axios from 'axios';\n\nconst asyncTask = store =&gt; done =&gt; (options) =&gt; {\n  const { method, url, payload } = options;\n  const params = method === 'get' ? { params: payload } : payload;\n\n  axios[method](url, params).then((error, response) =&gt; done(error, response));\n};\n\n// create the async middleware\nconst asyncMiddleware = createAsyncMiddleware(asyncTask);\n\n// set it to the Store\nconst store = createStore(\n  reducer,\n  applyMiddleware(asyncMiddleware),\n);\n</code></pre>\n\n<blockquote>\n<p>In the above example, we are using axios, but you can use whatever you want to perform the request, just make sure you call done, passing error and response when the request ends.</p>\n</blockquote>\n<p>For more info about <strong>asyncTask</strong> and <strong>createAsyncMiddleware</strong>, read <a href=\"http://redux-arc.js.org/docs/basics/ConnectingArcIntoRedux.html\">Connecting Arc Into Redux</a></p>\n<h1 id=\"reducers\"><a name=\"user-content-reducers\" href=\"#reducers\" class=\"headeranchor-link\" aria-hidden=\"true\"><span class=\"headeranchor\"></span></a>Reducers</h1>\n<p>Beyond types and action creators, we also have reducers. There are a few ways to deal with them, some approaches use <code>switch case</code>, some others use multiple <code>IFs</code>. With most of them, you end up having a lot of code inside the same function, which makes maintenance and focusing hard. I know some approaches mention that you can split your code into small functions when it gets bigger, but why do not start from something that is easy to scale and also allow you to focus on each action separately?</p>\n<p>Thinking about that, we created the function <code>createReducers</code></p>\n<p><strong>createReducers</strong></p>\n<p>This factory was created to work standalone, it doesn&rsquo;t require you to use any other feature from Arc. If you like, you can continue creating your actions and types as you always did. Take a look at the example below:</p>\n<pre><code class=\"js\">  // vanillaActions.js\n  export const ADD_NEW_JEDI = 'ADD_NEW_JEDI';\n\n  export const addNewJedi = (name, master) =&gt; ({\n    type: ADD_NEW_JEDI,\n    name,\n    master,\n  });\n\n</code></pre>\n\n<p>Above we defined our types and action creator using pure JavaScript . Below, you can see how we could use it with <strong>createReducers</strong>:</p>\n<pre><code class=\"js\">  import { createReducers } from 'redux-arc';\n  import { ADD_NEW_JEDI } from './vanillaActions';\n\n  const INITIAL_STATE = [];\n\n  const onAddNewJedi = (state, action) =&gt; [\n    ...state,\n    { name: action.name, master: action.master },\n  ];\n\n  const HANDLERS = {\n    [ADD_NEW_JEDI]: onAddNewJedi\n  };\n\n  export default createReducers(INITIAL_STATE, HANDLERS);\n</code></pre>\n\n<p>You must provide a INITIAL_STATE and a HANDLERS object, which the keys should be the action types and the values should be reducers.</p>\n<p><strong>Using createActions with arc&rsquo;s types object</strong><br />\nAs the types object is a simple JavaScript object, with strings, it fits perfectly with <strong>createReducers</strong>. Take a look below in an example using both, a regular and a async action with <strong>createReducers</strong>:</p>\n<p><strong>actions.js</strong>:</p>\n<pre><code class=\"js\">  const { creators, types } = createActions('todo', {\n    list: { url: 'api/todo', method: 'get'  }, // async action\n    reset: null, // regular action,\n  });\n</code></pre>\n\n<p><strong>reducers.js</strong></p>\n<pre><code class=\"js\">import { createReducers } from 'redux-arc'\nimport { types } from './actions';\n\nconst INITIAL_STATE = {\n  listResult: [],\n  listIsLoading: false,\n  listError: null,\n};\n\nconst onListRequest = (state, action) =&gt; ({\n  ...state,\n  listIsLoading: true,\n  listError: INITIAL_STATE.listError,\n});\n\nconst onListResponse = (state, action) =&gt; {\n  if (action.error) {\n    return {\n      ...state,\n      listIsLoading: INITIAL_STATE.listIsLoading,\n      listError: action.payload,\n    }\n  }\n\n  return {\n    ...state,\n    listIsLoading: INITIAL_STATE.listIsLoading,\n    listResult: action.payload\n  }\n};\n\nconst onReset = state =&gt; INITIAL_STATE;\n\nconst HANDLERS = {\n  [types.LIST.REQUEST]: onListRequest,\n  [types.LIST.RESPONSE]: onListResponse,\n  [types.RESET]: onReset,\n};\n\nexport default createReducers(INITIAL_STATE, HANDLERS);\n</code></pre>\n\n<p>As we mentioned, we are using two kinds of action types, regular and async.</p>\n<p>For the regular, there&rsquo;s no much secret, <code>types.RESET</code> contains a string <code>TODO_RESET</code> generated by <code>createActions</code>, using the namespace and the action name we defined earlier.</p>\n<p>The async action, contains an object, with <strong>REQUEST</strong> and <strong>RESPONSE</strong> keys, each one containing a string, which is the actual type.</p>\n<p>Arc will dispatch the respective request and response action using the same types we have in <code>types</code> object and the same applies for regular actions, so Arc doesn&rsquo;t open breaches for you to commit a typo.</p>\n<h1 id=\"async-actions_1\"><a name=\"user-content-async-actions_1\" href=\"#async-actions_1\" class=\"headeranchor-link\" aria-hidden=\"true\"><span class=\"headeranchor\"></span></a>Async Actions</h1>\n<h3 id=\"response-action\"><a name=\"user-content-response-action\" href=\"#response-action\" class=\"headeranchor-link\" aria-hidden=\"true\"><span class=\"headeranchor\"></span></a>Response action:</h3>\n<p>When the request is done, an action with the response will be dispatched. Considering the list example, the response action would look like this:</p>\n<pre><code class=\"js\">{\n  type: 'JEDI_LIST_RESPONSE', // types.LIST.RESPONSE,\n  meta: {\n    url: 'api/todo',\n    method: 'get',\n  },\n  payload: [\n    // resource list\n  ],\n}\n</code></pre>\n\n<h3 id=\"error-handling\"><a name=\"user-content-error-handling\" href=\"#error-handling\" class=\"headeranchor-link\" aria-hidden=\"true\"><span class=\"headeranchor\"></span></a>Error handling</h3>\n<p>The above example is a a response with success. Accordingly to <strong>FSA</strong>, errors should be treated as a <a href=\"https://github.com/redux-utilities/flux-standard-action#errors-as-a-first-class-concept\"><strong>First class concept</strong></a>. In that case, when you got some error in an async request, the response action will come with the error property as <code>true</code> and the payload will be the actual error. Just like the example below:</p>\n<pre><code class=\"js\">{\n  type: 'JEDI_LIST_RESPONSE', // types.LIST.RESPONSE,\n  meta: {\n    url: 'api/todo',\n    method: 'get',\n  },\n  payload: new Error('the request error'),\n  error: true,\n}\n</code></pre></article></body></html>\n"
  },
  {
    "path": "README.md",
    "content": "<img src=\"https://github.com/viniciusdacal/redux-arc/blob/master/arc-64.png?raw=true\" width=\"200\" />\n\nCreate scalable, no-boilerplate redux Apps!\n\nArc is an abstraction layer to help you reduce boilerplate on redux-apps and also, organize better your code. Additionally, it has utilities to handle async requests.\n\n[![build status](https://img.shields.io/travis/viniciusdacal/redux-arc/master.svg?style=flat-square)](https://travis-ci.org/viniciusdacal/redux-arc) [![npm version](https://img.shields.io/npm/v/redux-arc.svg?style=flat-square)](https://www.npmjs.com/package/redux-arc)\n[![Coverage Status](https://coveralls.io/repos/github/viniciusdacal/redux-arc/badge.svg?branch=master)](https://coveralls.io/github/viniciusdacal/redux-arc?branch=master)\n\n## Why\nRedux is awesome! But people often complain about how much boilerplate they have to write when using it. Part of this problem, is because they feel unproductive defining constants, action creators and big reducers, but also because they don't have a clear idea on how to organize their project, or even how to proper handle async requests. This project, intends to help on all that aspects!\n\nWe don't intend to recreate the wheel, instead, we tried to use what the community are used with, and build up some approaches together in order to clarify the things about the project architecture, code splitting and the things around actions.\n\n## Action creators and types generated by a config\n\n```js\n  // actions.js\n  import { createActions } from 'redux-arc';\n\n  export { types, creators } = createActions('jedi', {\n    add: null,\n    reset: null\n  });\n```\n\n## Create reducers reusing types and without switch cases:\n\n```js\n  import { createReducers } from 'redux-arc';\n  import { types } from './actions';\n\n  const INITIAL_STATE = [];\n\n  const onAdd = (state, action) => [\n    ...state,\n    action.payload,\n  ];\n\n  const onReset = () => INITIAL_STATE;\n\n  const HANDLERS = {\n    [types.ADD]: onAdd,\n    [types.RESET]: onReset,\n  };\n\n  export default createReducers(INITIAL_STATE, HANDLERS);\n```\n\n## Call the creators providing payload and meta\n\n```js\n  import { creators } from './actions';\n\n  const payload = { name: 'Luke' };\n  const meta = { foo: 'bar' };\n\n  dispatch(creators.add(payload, meta));\n  /*\n  {\n    type: 'JEDI_ADD',\n    payload: { name: 'luke' },\n    meta: { foo: 'bar' },\n  }\n  */\n\n  dispatch(creators.reset());\n  // { type: 'JEDI_RESET' }\n```\n\n## Create Async Actions\n\n```js\n  import { createActions } from 'redux-arc';\n\n  export { types, creators } = createActions('jedi', {\n    add: { url: '/api/jedi' method: 'post'},\n  });\n\n  dispatch(creators.add(payload, meta));\n\n  types.ADD.REQUEST // JEDI_ADD_REQUEST\n  types.ADD.RESPONSE // JEDI_ADD_RESPONSE\n```\n> createActions creates both, regular and **Async Actions**. Async types has **REQUEST** and **RESPONSE** type, respectively to when a request starts and when it finishes.\n\n\n## Demo Project\nTake a look at the demo project using Arc to build a Contacts CRUD: [github.com/redux-arc/redux-arc-demo](https://github.com/redux-arc/redux-arc-demo)\n\n# Getting started\n\n```bash\nyarn add redux-arc\n```\n\nor\n\n```bash\nnpm i --save redux-arc\n```\n\n\nTo understand this docs, you should have a good understand of redux: what are Action creators, what are reducers, middlewares and also, what is a Flux Standard Action. So please, if you need a recap on those concepts, read the links bellow:\n\n[Redux Docs](https://redux.js.org/)\n[Flux Standard Action](https://github.com/acdlite/flux-standard-action)\n\n\n# Action creators and Types\nWhen you have to create a new action on redux, the first 2 steps you usually do is defining a **const** to you *action type* and then defining an *action creator*.\n\n```js\nconst ADD_JEDI = 'ADD_JEDI';\n\nconst addJedi = (payload) => ({\n  type: ADD_JEDI,\n  payload,\n});\n```\n\nThe above code is fine, but the problem is, you have dozens or hundreds of action in an application, and you are always writing the same code. Also, if you are not strict on code review, you end up having situations where your action type has a name different from your action creator:\n\n```js\nconst ADD_JEDI = 'ADD_JEDI';\n\nconst addJedi = (payload) => ({\n  type: ADD_JEDI,\n  payload,\n});\n```\n\nThinking in the above issues, Arc has a `createAction` function, that you use to define your actions and it generates the types and action creators automatically for you. Take a look:\n\n```js\n  import { createActions } from 'redux-arc';\n\n  const { types, creators } = createActions('yourNamespace', {\n    addJedi: null,\n  });\n\n  types.addJedi // YOUR_NAMESPACE_ADD_JEDI\n\n  const payload = {\n    master: 'Yoda',\n    name: 'Luke',\n  };\n\n  creators.addJedi(payload);\n  /*\n  {\n    type: 'YOUR_NAMESPACE_ADD_JEDI',\n    payload: {\n      master: 'Yoda',\n      name: 'Luke',\n    }\n  }\n  */\n```\n\nThe `createActions` method, expects a namespace as its first argument, this will be uppercased and will serve as a prefix for the actions. As the second parameter, we need to provide a config object, which the key is the action name and the value is an object with default values for **payload** and **meta**, or `null` if you don't want to provide defaults. Then, it will return **creators** and **types**.\n\nBoth creators and types are objects, the first one contains the action creators for the actions you defined. As in the case above we defined an action addJedi, then we have a creator at `creators.addJedi`.\n\nCreators accepts until three arguments:\n - payload: could be of any type. Will become the `action.payload`\n - meta: could be of any type. Will become the `action.meta`\n - error: boolean. Indicates if the action has an error or not. You can omit it if the action has no error.\n\n> The api was designed following the flux-standard-action concepts. It can be strict about how your action should look like, but this will help you creating better actions. Also, now you can be sure that the first parameter you provide to the action creator, will become the action.payload.\n\nThe types is an object that contains strings. Its keys are the action names, but different from the creators, here they are uppercased:\n\n```js\n  types.ADD_JEDI\n```\n\nAlso, when you do a console.log to see its content, you can see that we prefix the actions with the namespace you provided:\n\n```js\n  const { types } = createActions('yourNamespace', {\n    addJedi: null,\n  });\n\n  types.ADD_JEDI // -> YOUR_NAMESPACE_ADD_JEDI\n\n```\n\n> We decided to have the namespace, to not stop you from having actions with the same name in different modules. Don't worry, you will be able to differ them easily when using redux-dev-tools, just remember to provide unique namespaces.\n\n# Reducers\n\nBeyond types and action creators, we also have reducers. There are a few ways to deal with them, some approaches use `switch case`, some others use multiple `IFs`. With most of them, you end up having a lot of code inside the same function, which makes maintenance and focusing hard. I know some approaches mention that you can split your code into small functions when it gets bigger, but why do not start from something that is easy to scale and also allow you to focus on each action separately?\n\nThinking about that, we created the function `createReducers`\n\n## createReducers\n\nThis factory was created to work standalone, it doesn't require you to use any other feature from Arc. If you like, you can continue creating your actions and types as you always did. Take a look at the example below:\n\n```js\n  // vanillaActions.js\n  export const ADD_TODO = 'ADD_TODO';\n  export const RESET_TODOS = 'RESET_TODOS';\n\n  export const addTodo = (title, completed) => ({\n    type: ADD_TODO,\n    payload: {\n      title,\n      completed,\n    }\n  });\n\n  export const resetTodos = () => ({\n    type: RESET_TODOS,\n  });\n\n```\n\nAbove we defined our type and action creator using pure JavaScript. Below, you can see how we could use it with **createReducers**:\n\n```js\n  import { createReducers } from 'redux-arc';\n  import { ADD_TODO, RESET_TODOS } from './vanillaActions';\n\n  const INITIAL_STATE = [];\n\n  const onAddTodo = (state, action) => [\n    ...state,\n    { name: action.name, master: action.master },\n  ];\n\n  const onResetTodos = (state, action) => INITIAL_STATE;\n\n  const HANDLERS = {\n    [ADD_TODO]: onAddTodo\n    [RESET_TODOS]: onResetTodos\n  };\n\n  export default createReducers(INITIAL_STATE, HANDLERS);\n```\n\nYou must provide an `INITIAL_STATE` and a `HANDLERS` object, which the keys should be action types and the values should be reducers.\n\n\n**Using createReducers with arc's types object**\nAs types generated from Arc is a simple JavaScript object, with strings, it fits perfectly with **createReducers**. Take a look below:\n\n**actions.js**:\n\n```js\n  const { creators, types } = createActions('todo', {\n    addTodo: null,\n    resetTodos: null,\n  });\n```\n\n**reducers.js**\n\n```js\nimport { createReducers } from 'redux-arc'\nimport { types } from './actions';\n\nconst INITIAL_STATE = [];\n\nconst onAddTodo = (state, action) => [\n  ...state,\n  { name: action.name, master: action.master },\n];\n\nconst onResetTodos = (state, action) => INITIAL_STATE;\n\nconst HANDLERS = {\n  [types.ADD_TODO]: onAddTodo\n  [types.RESET_TODOS]: onResetTodos\n};\n\nexport default createReducers(INITIAL_STATE, HANDLERS);\n\n```\n\nAs you can see, you can use **createReducers** either standalone or with types generated by Arc.\n\nIt helps you organize your logic and focus on how each action will affect the state;\n\nAlso, it runs some validations over the config you provided. For example: If you commit a typo when providing the action type, it will throw a friendly descriptive error for you.\n\n\n# Async Actions\n\nOriginally, Arc was created to be an abstraction layer to handle async request in Redux. So, it has all you need about that. The api to generate async action creators and types is the same we use for regular actions, you only need to provide some additional params in the action config object. Take a look below:\n\n\n```js\n  import { createActions } from 'redux-arc';\n\n  const { creators, types } = createActions('todo', {\n    list:   { url: 'api/todo',     method: 'get'  },\n    read:   { url: 'api/todo/:id', method: 'get'  },\n    create: { url: 'api/todo',     method: 'post' },\n    update: { url: 'api/todo/:id', method: 'put'  },\n  });\n```\n\nAbove are defined four actions: `list`, `read`, `create` and `update`.\n\nTwo params are required in an async action config, `url` and `method`.\n\n - **url**: You can define any url you want and it also accepts dynamic params, as you can see in the `read` action. We defined a dynamic param **id**, inserting `:id`.\n - **method**: Generally speaking, any http method your request lib supports. This will be used only by you in the **asyncMiddleware** that you will configure.\n\n### Async Creators and Async Types\nAn async creator is very similar to a simple creator. It accepts **payload** and **meta** as arguments. They will further become the `action.payload` and `action.meta`, as in a regular creator. The difference here, is that the meta, should be an object, and its values will be also used to parse dynamic urls. Considering that, the creator **read** should be used like that:\n\n```js\n  const payload = null;\n  const meta = { id: '123' };\n\n  creators.read(payload, meta);\n```\n\nWith the above code, the final url to our read request, would be `api/todo/123`.\n\nThe async types differ a little bit from the regular ones as well. First, as a api call has two moments (request and response), we need two different types to use inside our reducers. Considering that, Arc returns an object for each type, containing a `REQUEST` and a `RESPONSE` key with the respective types:\n\n```js\n  types.READ.REQUEST == 'TODO_READ_REQUEST';\n  types.READ.RESPONSE == 'TODO_READ_RESPONSE';\n```\n\n### Async Middleware\nArc doesn't intend to be a request lib, so, you need to tell it how you want to make your requests, and you do that by configuring the asyncMiddleware.\n\nIt's quite simple, take a look below in an example using axios:\n\n```js\nimport { createAsyncMiddleware } from 'redux-arc';\nimport axios from 'axios';\n\nconst asyncTask = store => done => (options) => {\n  const { method, url, payload } = options;\n  const params = method === 'get' ? { params: payload } : payload;\n\n  return axios[method](url, params).then(\n    response => done(null, response.data),\n    error => done(error, null),\n  );\n};\n\n// create the async middleware\nconst asyncMiddleware = createAsyncMiddleware(asyncTask);\n\n// set it to the Store\nconst store = createStore(\n  reducer,\n  applyMiddleware(asyncMiddleware),\n);\n```\n\n>In the above example, we are using axios, but you can use whatever you want to perform the request, just make sure you call done, passing error and response when the request has finished.\n\nFor more info about **asyncTask** and **createAsyncMiddleware**, read [Connecting Arc Into Redux](http://redux-arc.js.org/docs/basics/ConnectingArcIntoRedux.html)\n\n\n## Async actions in Reducers\n\nIn reducers, you have to define two different handlers for each request definition, one to handle the state change when the request starts an another when it finishes.\n\nConsidering the following config:\n\n```js\n  import { createActions } from 'redux-arc';\n\n  export const { creators, types } = createActions('todo', {\n    list: { url: 'api/todo', method: 'get' },\n  });\n```\n\nWe would have a reducers like this:\n\n```js\nimport { createReducers } from 'redux-arc'\nimport { types } from './actions';\n\nconst INITIAL_STATE = {\n  listResult: [],\n  listIsLoading: false,\n  listError: null,\n};\n\nconst onListRequest = (state, action) => ({\n  ...state,\n  listIsLoading: true,\n  listError: INITIAL_STATE.listError,\n});\n\nconst onListResponse = (state, action) => {\n  if (action.error) {\n    return {\n      ...state,\n      listIsLoading: INITIAL_STATE.listIsLoading,\n      listError: action.payload,\n    }\n  }\n\n  return {\n    ...state,\n    listIsLoading: INITIAL_STATE.listIsLoading,\n    listResult: action.payload\n  }\n};\n\nconst onReset = state => INITIAL_STATE;\n\nconst HANDLERS = {\n  [types.LIST.REQUEST]: onListRequest,\n  [types.LIST.RESPONSE]: onListResponse,\n  [types.RESET]: onReset,\n};\n\nexport default createReducers(INITIAL_STATE, HANDLERS);\n```\n\n\n### Response action:\nWhen the request is done, an action with the response will be dispatched. Considering the list example, the response action would look like this:\n\n```js\n{\n  type: 'JEDI_LIST_RESPONSE', // types.LIST.RESPONSE,\n  meta: {\n    url: 'api/todo',\n    method: 'get',\n  },\n  payload: [\n    // resource list\n  ],\n}\n```\n\n### Error handling\nThe above example is a response with success. Accordingly to **FSA**, errors should be treated as a [**First class concept**](https://github.com/redux-utilities/flux-standard-action#errors-as-a-first-class-concept). In that case, when you got some error in an async request, the response action will come with the error property as `true` and the payload will be the actual error. Just like the example below:\n\n```js\n{\n  type: 'JEDI_LIST_RESPONSE', // types.LIST.RESPONSE,\n  meta: {\n    url: 'api/todo',\n    method: 'get',\n  },\n  payload: new Error('the request error'),\n  error: true,\n}\n```\n\n\n"
  },
  {
    "path": "book.json",
    "content": "{\n  \"gitbook\": \"3.2.2\",\n  \"title\": \"Redux Arc\",\n  \"plugins\": [\"edit-link\", \"prism\", \"-highlight\", \"github\", \"anchorjs\"],\n  \"pluginsConfig\": {\n    \"edit-link\": {\n      \"base\": \"https://github.com/viniciusdacal/redux-arc/tree/master\",\n      \"label\": \"Redux Arc\"\n    },\n    \"github\": {\n      \"url\": \"https://github.com/viniciusdacal/redux-arc/\"\n    },\n    \"theme-default\": {\n      \"styles\": {\n        \"website\": \"build/gitbook.css\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "build/gitbook.css",
    "content": ".book-summary ul.summary li span {\n  cursor: not-allowed;\n  opacity: 0.3;\n}\n\n.book-summary ul.summary li a:hover {\n  color: #008cff;\n  text-decoration: none;\n}\n"
  },
  {
    "path": "docs/README.md",
    "content": "Table of Contents\n* [Read Me](/README.md)\n\n* [Basics](/docs/basics/README.md)\n  * [Action Creators](/docs/basics/ActionCreators.md)\n  * [Action Types](/docs/basics/ActionTypes.md)\n  * [Creating Async Middleware](/docs/basics/CreatingAsyncMiddleware.md)\n  * [Requests Definition](/docs/basics/RequestsDefinition.md)\n\n* [Advanced](/docs/advanced/README.md)\n  * [Request Middlewares](/docs/advanced/RequestMiddlewares.md)\n"
  },
  {
    "path": "docs/advanced/README.md",
    "content": "## Advanced\n\n* [Request Middlewares](RequestMiddlewares.md)\n"
  },
  {
    "path": "docs/advanced/RequestMiddlewares.md",
    "content": "# Request Middlewares\nRequest middlewares, as the name says, are middlewares that you can apply to specific requests. Lets say you want to format your payload before the request, but only in a few cases. Or you would like to process some response, before it goes to the reducers. For all these edge cases, you can use a request middleware.\n\n# Saving a session token into localStorage\nLet's imagine you have a login request, that returns a session token in case of success. On the response, you need to get that token and save it to the browser's localStorage. That could be fairly easy to handle with a middleware.\n\nLet's take a look into the whole code for that and then go through it, step by step.\n\nBelow you can see the middleware's code:\n\n```js\n// saveUserSession.js\nfunction saveUserSession() {\n  return done => (action, error, response) => {\n    if (response && response.token) {\n      localStorage.setItem('$token', response.token);\n    }\n    return done(action, error, response);\n  };\n}\nsaveUserSession.applyPoint = 'onResponse';\n\nexport default saveUserSession;\n```\n\nAs we can observe in the above code, request middlewares are very similar to redux's middlewares. The big difference is that redux middlewares watches all application actions, while request middlewares you apply as you need, for specific requests.\n\nA middleware should also contain a property `applyPoint`, which should be either `'onRequest'` or `'onResponse'`. The applyPoint tells in which moment of the request the middleware will be executed. Considering we need the token that comes in the response, we use the applyPoint `'onResponse'`.\n\nGoing to the code inside the middleware, we call the function **done**, passing the same params we received. We do that because we don't want to intercept the action or modify the response, we only intend to use the response value. But we still do a **return** of the result of **done**, to not break the promise chain.\n\nAfter that, we check if the response is valid and then we save the token in the localStorage.\n\n\n## Applying middlewares to requests\nTo use a middleware, is fairly simple, you only need to *import* and include it in an array under a property **middlewares** in the action config. Take a look at the following example:\n\n\n```js\nimport { createActions } from 'redux-arc';\nimport saveUserSession from  './saveUserSession';\n\nconst { types, creators } = createActions('user', {\n  login: {\n    url: 'user/login',\n    method: 'post',\n    middlewares: [saveUserSession],\n  },\n});\n\ndispatch(creators.login({\n  email: 'user@test.com',\n  password: '123',\n}));\n```\n\n\nWe are defining a login request, and we are applying the middleware we created to it. Then, we use the creator to dispatch the action that will start the request, passing the email and password in the payload.\n\nproviding the middleware in the config, makes the middleware run every time you call that request. But let's say you would like to apply the middleware in a single call to that request, then you could do the following:\n\n```js\nimport saveUserSession from  './saveUserSession';\n\nconst { types, creators } = createActions('user', {\n  login: {\n    url: 'user/login',\n    method: 'post',\n  },\n});\n\ndispatch(creators.login({\n  email: 'user@test.com',\n  password: '123',\n  middlewares: [saveUserSession],\n}));\n```\n\nIn the code above, instead of apply the middleware to all login requests, we apply to the single call we are doing.\n\n## onRequest middlewares\nIn the previous example we used the applyPoint `'onResponse'`, because we wanted to access the response value. In the following example, we are going to use the applyPoint `'onRequest'`, because we will process and change the payload before it goes to the request.\n\n\n## Saving an user\nSo, let's imagine you would like to create and update a user, but you wouldn't like to configure two different requests to do that. You would rather to config a single request named **save** and when you call it passing a user without an id, it would understand that you were intending to do a creation request, otherwise, it would assume you were trying to update the user, and would do the necessary changes on the request data to ensure the update would work. You could create a middleware to handle that scenario, and name it **createOrUpdate**. Let's do it.\n\n\n```js\nfunction createOrUpdate() {\n  return done => (action, error, response) => {\n    const { payload, meta } = action;\n\n    if (!payload.id) {\n      return done(action, error, response);\n    }\n\n    const { id, ...user } = payload;\n\n    const updateAction = {\n      ...action,\n      payload: user,\n      meta: { url: `${meta.url}/${id}`, method: 'put', id },\n    };\n    return done(updateAction, error, response);\n  }\n}\ncreateOrUpdate.applyPoint = 'onRequest';\n\nexport default createOrUpdate;\n```\n\n> In the cases your middleware has an applyPoint `onRequest`, you would have access only to the `action` object, unless another middleware created an  `error` or `response` in the `onRequest` chain.\n\nThe first thing we do in the middleware, is check for the `payload.id`. If none is present, we assume this request intends to create an user and we assume the original request config is prepared to do that, having the method as `post`, and having the proper url for the creation. That said, we only need to let the request happens normally, calling the function **done**, passing the params we received.\n\nIf there's an id present, we create another action, modifying the **url** to include the **id** and also changing the method, to `put`. Once we do that, we only need to call **done**, providing modified action.\n\nAnd that's it, our **createOrUpdate** middleware is done. Now, let's take a look on how to use it.\n\n```js\nimport { createActions } from 'redux-arc';\nimport createOrUpdate from  './createOrUpdate';\n\nconst { types, creators } = createActions('user', {\n  save: {\n    url: 'user',\n    method: 'post',\n    middlewares: [createOrUpdate]\n  },\n});\n\ndispatch(creators.save({\n  name: 'My New user',\n  email: 'user@redux-arc.js.org',\n}));\n\ndispatch(creators.save({\n  id: '123'\n  name: 'My Edited user',\n  email: 'user@redux-arc.js.org',\n}));\n```\n\nFirst, we define the request as it would be for the creation, passing the url as `user` and the method as `post`. Then, we add the middleware to it.\n\nIn the first dispatching, the payload does not contain the id, so it will create an user. The second dispatch contains the id and will be an update.\n\n> Usually, for `onRequest` you would change only the action value, and for `onResponse`, you would change only the response. But feel free to change the action inside  `onResponse` cycle if that makes sense.\n\nRemember that when you create a middleware, you can use it in different request. This last middleware for example, you could use to create and save todo items, or into any crud your application has.\n\nRequest middlewares can be used in many different ways, adding flexibility to the requests.\n"
  },
  {
    "path": "docs/basics/ActionCreators.md",
    "content": "# Action Creators\n\nAn action creator, is a function that returns an action. Simple action creators should look just like this:\n\n```js\n\n  const add = payload => ({\n    type: 'TODO_ADD',\n    payload,\n  });\n\n  const reset = () => ({\n    type: 'TODO_RESET',\n  });\n```\n\nThe problem is, when you are in a real project, you will have far more actions than only two, and you always have to define these creators.\n\n99% of times, they are just like the code above. You always have to define a name for your **creator**, then you have to define a **type** that has (or at least should) the same name as the **creator**, but uppercased. Then you receive some arguments in the function, inject them in the action and return the action. This process is too repetitive.\n\nTo solve that issue, Arc has the `createActions` method, which generates types and action creator for you, based on a config.\n\nTake a look at the example below:\n\n```js\n  import { createActions } from 'redux-arc';\n\n  const { creators } = createActions('todo', {\n    add: null,\n    reset: null,\n  })\n```\n\n\nThe above config would generate a **creators**, similar to the object below:\n\n```js\n  {\n    add: function (payload, meta, error) {},\n    reset: function (payload, meta, error) {},\n  }\n```\n\nThose action creators can be used the same way as regular action creators are. So, having access to `dispatch` function, you can just do the following:\n\n```js\n  const payload = {\n    // any payload\n  };\n  const meta {\n    // any meta\n  };\n  dispatch(creators.add(payload, meta));\n\n  /*\n  {\n    type: 'TODO_ADD',\n    payload: {},\n    meta: {},\n  }\n  */\n```\n\nThe arguments `payload` and `meta` are not required. To dispatch a *reset action*, for example, as we are not going to use either **payload** neither **meta** inside our reducers, we can call the creator straight away, without passing any argument:\n\n```js\n  dispatch(creators.reset());\n\n  /*\n  {\n    type: 'TODO_RESET',\n  }\n  */\n```\n\n## Providing default payload and meta for the action\nYou may be asking yourself why we always have to provide a `null` in the action config. One of the reasons, is because we accept some extra options to generate the actions. You could provide a default `payload`, a default `meta` or a default `error`, for example:\n\n```js\n\n  const anyDefaultPayload = {};\n  const anyDefaultMeta = {};\n\n  const { creators } = createActions('todo', {\n    add: {\n      payload: anyDefaultPayload,\n      meta: anyDefaultMeta,\n      error: false, // always a boolean;\n    },\n    reset: null,\n  });\n```\n\nBesides a default values, Arc also accepts a param `url`, which will create a different kind of action, a **async action**.\n\n\n# Async Action\n\nBy Arc's point of view, a async action that contains the necessary information to trigger a async request. It has some additional info, as `url` and `method` and it also has two types instead of just one.\n\nThrough the `createActions` factory, Arc allows you to create **async creators** and **async types** too, in order to make your life easier when you need to deal with this subject. The way you generate them is very similar to regular actions. Take a look below:\n\n\n```js\nconst { creators } = createActions('todo', {\n  list: { url: 'api/todo', method: 'get' },\n  update: { url: 'api/todo/:id', method: 'put' },\n  reset: null,\n})\n```\n\nAs you can see, the api is nearly the same, you just need to provide the params `url` and `method` to make it work.\n\n - **url**: an endpoint to make the requests. It also accepts dynamic params, as you can see in the config to **update** request. We defined a `:id` which will be parsed when we call the creator providing the actual param.\n - **method**: Any http method your request lib supports. ('get', 'post', etc...)\n - **middlewares**: Arc also accepts middlewares in the action config, to give you flexibility to handle edge cases. You can check them at: [Request Middlewares](http://redux-arc.js.org/docs/advanced/RequestMiddlewares.html)\n\n\nGiven the above config, to start a list request, you could just do the following:\n\n```js\n  dispatch(creators.list());\n```\n\nFirst, `creators.list` will return the following action:\n\n```js\n  {\n    type: ['MY_NAMESPACE_LIST_REQUEST', 'MY_NAMESPACE_LIST_RESPONSE'],\n    meta: {\n      url: 'api/todo',\n      method: 'get',\n    },\n  }\n```\n\nAnd then, the function dispatch, will dispatch it for redux.\n\nThe way we use `creators.update` is very similar, the only two differences are:\n - We need to provide a **payload**, that will be the request's payload itself.\n - We need to provide a param **id**, that will be used to parse the dynamic url.\n\nTake a look in the example below:\n\n```js\n  const payload = {\n    description: 'Implement Arc in the project',\n    date: '2017-10-03',\n  };\n\n  const meta = { id: '123' };\n\n  dispatch(creators.update(payload, meta));\n```\n\nThe above creator, generates the following action:\n\n```js\n  {\n    type: ['MY_NAMESPACE_UPDATE_REQUEST', 'MY_NAMESPACE_UPDATE_RESPONSE'],\n    payload: {\n      description: 'Implement Arc in the project',\n      date: '2017-10-03',\n    },\n    meta: {\n      url: 'todo/123',\n      method: 'put',\n      id: '123',\n    },\n  }\n```\n\n> When the above action is dispatched, Arc's middleware intercepts it, parses the values and passes the options to **asyncTask** perform the request.\n\nNotice that, those actions generated by Arc's creators, have an array containing two strings instead of being only a simple string. That's how Arc's middleware identifies them as Async Actions. Also, the first type is used in the action dispatched right before the request starts and the second is used to dispatch an action right after we get a response.\n\n## Providing url as function\nArc also supports url as a function that expects params as its first argument and returns a string, as the following example:\n\n```js\nconst { creators } = createActions('todo', {\n  read: {\n    url: params => `todo/${params.id}`,\n    method: 'get',\n  }\n})\n```\n"
  },
  {
    "path": "docs/basics/ActionTypes.md",
    "content": "# Action Types\nBeyond creators, you also receive an object named **types** when you call `createActions`. This object contains all the respective types for your actions.\n\nGiven the following config:\n\n```js\nconst { types } = createActions('myNamespace', {\n  list: { url: 'todo', method: 'get' },\n  update: { url: 'todo/:id', method: 'put' },\n  reset: null,\n});\n```\n\nYour action types would look exactly like this:\n\n```js\n{\n  LIST: {\n    REQUEST: 'MY_NAMESPACE_LIST_REQUEST',\n    RESPONSE: 'MY_NAMESPACE_LIST_RESPONSE',\n  },\n  UPDATE: {\n    REQUEST: 'MY_NAMESPACE_UPDATE_REQUEST',\n    RESPONSE: 'MY_NAMESPACE_UPDATE_RESPONSE',\n  },\n  RESET: 'MY_NAMESPACE_RESET',\n};\n```\n\nConsidering the code above, to get the type for your list response action, you could do the following:\n\n```js\n  types.LIST.RESPONSE // MY_NAMESPACE_LIST_RESPONSE\n```\n\n**The logic we use to define the types, is basically:**\n\nConvert the action name to Upper Case, splitting words by underscore `_` and use it as the root keys of our action types object:\n\n ```js\n  // list -> LIST\n  {\n    LIST,\n    UPDATE,\n    RESET,\n  }\n ```\n\n\n\nFor async types, we add the keys `REQUEST` and `RESPONSE` to all types objects:\n\n ```js\n  // list ->\n  {\n    LIST: {\n      REQUEST,\n      RESPONSE,\n    },\n    UPDATE: {\n      REQUEST,\n      RESPONSE,\n    },\n    RESET,\n  }\n ```\n\nThe final value for the action type, begins with the namespace uppercased, followed by the action name uppercased.  For **Async Actions**, we append respectively, the words `REQUEST` and `RESPONSE`).\n\n```\n  myNamespace -> MY_NAMESPACE\n  list -> LIST\n  reset -> RESET\n\n  MY_NAMESPACE_LIST_REQUEST\n  MY_NAMESPACE_LIST_RESPONSE\n\n  MY_NAMESPACE_RESET\n```\n"
  },
  {
    "path": "docs/basics/CreatingAsyncMiddleware.md",
    "content": "# Creating Async Middleware\n\nThe first step to start using Arc's async actions, is to create the AsyncMiddleware and set it to the store.\n\n\n```js\nimport { createStore, applyMiddleware } from 'redux';\nimport { createAsyncMiddleware } from 'redux-arc';\n\nconst asyncTask = store => done => (options) => {\n  const { url, method, payload, ...meta } = options;\n\n  /* do your request and call done with the respective error and response\n     when the request is finished */\n  done(err, response))\n};\n\nconst asyncMiddleware = createAsyncMiddleware(asyncTask);\n\n// set it to the Store\nconst store = createStore(\n  reducer,\n  applyMiddleware(asyncMiddleware),\n);\n```\n\n### asyncTask\nNotice we defined a function named `asyncTask` on the first lines of the above example, that's because we leave the request call for you. Everytime you dispatch an async action, the middleware will call `asyncTask` passing the respective params. `asyncTask` should do the request and should call `done` when the request is finished, providing an error and a response. What you are going to use to perform your requests (fetch, promises, libs etc..), is up to you! Only make sure you call `done` in the proper time.\n\nPay attention to the `options` argument. The `asyncTask` should rely on this to perform the request. The `options` will be an object that contains `url`, `payload` and `method`.\n\nIf we remove all the promise related code, the `asyncTask` would look like this:\n\n```js\n  const asyncTask = store => done => options => {\n    const { url, method, payload, ...meta } = options;\n    done(error, response);\n  };\n```\n\n**Parameter**\n\nThe parameter `store`, is the actual redux store, with the methods `getState` and `dispatch`, use them with parsimony.\n\nThe parameter `done` is a function and should be called once the request is finished, with the **error** and **response**.\n\nThe parameter `options` will contain some fields extracted from the async action, which are the `url`, `method` the `payload` you provided when you call the action creator and all `action.meta` fields.\n\n### createAsyncMiddleware\nThis function waits as its first argument, the function `asyncTask`, and will return the actual middleware for redux. Then, you get the middleware and apply it to the store. Rather to set `asyncMiddleware` as the first middleware in the config, it will avoid traffic unnecessary  actions through the whole redux flow.\n\nAnd that's it, your middleware is configured in the store. Let's jump strait forward to the request definitions.\n\n"
  },
  {
    "path": "docs/basics/README.md",
    "content": "## Basics\n\n* [Action Creators](ActionCreators.md)\n* [Action Types](ActionTypes.md)\n* [Requests Definition](RequestsDefinition.md)\n* [Creating Async Middleware](CreatingAsyncMiddleware.md)\n* [Request and Response values](RequestAndResponseValues.md)\n"
  },
  {
    "path": "docs/basics/RequestAndResponseValues.md",
    "content": "# Request and response values\nWhen you start a request, dispatching an async action, There are two different actions that are dispatched by Arc. One action when the request starts, and another when it ends.\n\nLet's observe the following example:\n\n```js\nconst { creators, types } = createActions('todo', {\n  update: { url: 'todo/:id', method: 'put' }\n})\n```\n\nWe can start a request, by dispatching the async action:\n\n```js\n  dispatch(creators.update({\n    id: '123',\n    payload: {\n      description: 'Implement Arc in the project',\n      date: '2017-10-03',\n    }\n  }));\n```\n\n## Request action\nThen, Arc will dispatch an action notifying that the request has been started. The action would be like the following:\n\n```js\n  {\n    type: 'TODO_UPDATE_REQUEST',\n    meta: {\n      id: '123',\n      url: 'todo/123',\n      method: 'put',\n    },\n    payload: {\n      description: 'Implement Arc in the project',\n      date: '2017-10-03',\n    },\n  }\n```\n\nUsing the **types** object, you can have access to that action type, using the below code:\n\n```js\n  types.UPDATE.REQUEST\n```\n\nIn that case, you could start creating your reducer such as below:\n\n```js\nconst INITIAL_STATE = {\n  updateInProcess: false,\n  updateResult: null,\n  updateError: null,\n};\n\nfunction toDoReducer(state = INITIAL_STATE, action) {\n  if (action.type === types.UPDATE.REQUEST) {\n    return {\n      ...state,\n      updateError: INITIAL_STATE.updateError,\n      updateInProcess: true,\n    }\n  }\n  return state;\n}\n```\n\nIn the example above, every time a update request starts, we reset the value **updateError** for its initial state, which is `null`, we also set **updateInProcess** as true.\n\nIf we need, we could also use the **id**, **url** or **method** in our reducers, accessing it from **action.meta**\n\n## Response Action\nWhen the request ends, Arc will dispatch the response action, which would look like the following example:\n\n```js\n  {\n    type: 'TODO_UPDATE_RESPONSE',\n    meta: {\n      id: '123',\n      url: 'todo/123',\n      method: 'put',\n    },\n    payload: THE PROPER RESPONSE FROM YOUR ENDPOINT,\n  }\n```\n\nThe above example is considering a successful request. In case of error, the action would come with a key error and the value for it would be true. The payload would be the error itself. The error action would be like this:\n\n```js\n  {\n    type: 'TODO_UPDATE_RESPONSE',\n    meta: {\n      id: '123',\n      url: 'todo/123',\n      method: 'put',\n    },\n    error: true,\n    payload: THE PROPER ERROR,\n  }\n```\n\nLet's update our reducer based on the above examples:\n\n```js\nconst INITIAL_STATE = {\n  updateInProcess: false,\n  updateResult: null,\n  updateError: null,\n};\n\nfunction toDoReducer(state = INITIAL_STATE, action) {\n  if (action.type === types.UPDATE.REQUEST) {\n    return {\n      ...state,\n      updateError: INITIAL_STATE.updateError,\n      updateInProcess: true,\n    }\n  }\n  if (action.type === types.UPDATE.RESPONSE) {\n    if (action.error) {\n      return {\n        ...state,\n        updateInProcess: INITIAL_STATE.updateInProcess,\n        updateError: action.payload,\n      };\n    }\n    return {\n      ...state,\n      updateInProcess: INITIAL_STATE.updateInProcess,\n      updateResult: action.payload,\n    };\n  }\n  return state;\n}\n```\n\nIn the example above, first we check if the **action.error** is **true**, and if it's, we set the **action.payload** to **updateError** and we reset **updateInProcess** to its initial state.\n\nIf no error is present, we set the action.payload to updateResult but we also reset **updateInProcess**.\n\n"
  },
  {
    "path": "docs/basics/RequestsDefinition.md",
    "content": "# Async actions Definition\n\nArc provides a declarative interface to define async actions, that allows you to do this in a few lines of code. If you are used with any route system, you will feel like home, if you don't, it will take minutes for you to understand how it works.\n\nFirst of all, let's see how would look a todo list crud definition, considering a rest api:\n\nLet's consider our base url as `/api`:\n\n```js\nimport { createActions } from 'redux-arc';\n\nconst { types, actions } = createActions('todo', {\n  create: { url: '/api/todo',     method: 'post' },\n  read:   { url: '/api/todo/:id', method: 'get'  },\n  update: { url: '/api/todo/:id', method: 'put'  },\n  list:   { url: '/api/todo',     method: 'get'  },\n  list:   { url: '/api/todo',     method: 'get'  },\n});\n\nconst payload = null;\nconst meta = { id: '123' };\n\nactions.read(payload, meta); //dispatch read action\n\ntypes.READ.REQUEST // TODO_READ_REQUEST\ntypes.READ.RESPONSE // TODO_READ_RESPONSE\n\n```\n\n> In the above example, we have our baseUrl as `/api`. If you are using a lib like axios, you can set the **baseUrl** in its config, so, the url definition of `read`, for example, could look like this: `todo/:id` instead of this:`/api/todo/:id`\n\nLet's step back and explore each part of this request definition.\n\n#createActions\n\nThis function is only a factory that returns the action creators and the action types.\n\n```js\nimport { createActions } from 'redux-arc';\n\nconst { types, actions } = createActions('myNamespace', {\n  list: { url: 'path/to/list', method: 'get'},\n});\n```\n\n`createActions` expects a namespace as its first argument, that will be used to prefix the action types.\n\nThe second argument is the requests definition object, which should respect the following pattern:\n\n```js\n{\n  list: {\n    url: 'todo',\n    method: 'get',\n  },\n  update: {\n    url: 'todo/:id',\n    method: 'put',\n  }\n}\n```\n\nAs you can see, it's possible to define multiple requests in the same config object, you only need to give it an action name. Considering the above config:\n\n - **action name** - It's the name you give for each async action. It will be used to generate the action creator and also the action type. In the above example, we have `list` and `update`.\n\n - **url** - will be passed to `asyncTask` to perform the request. It also accepts dynamic urls, so, you can define an url such as `path/to/resource/:id`.\n\n - **method** - It will be passed to `asyncTask` as well, in this case, you can use any method your request lib supports, the most common are `post`,`get`, `put` and `delete`.\n\n\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"redux-arc\",\n  \"version\": \"0.7.5\",\n  \"description\": \"Abstraction layer to help you reduce boilerplate on redux-apps\",\n  \"main\": \"lib/index.js\",\n  \"module\": \"es/index.js\",\n  \"files\": [\n    \"dist\",\n    \"lib\",\n    \"src\"\n  ],\n  \"keywords\": [\n    \"redux\",\n    \"redux-arc\",\n    \"react\",\n    \"async\"\n  ],\n  \"scripts\": {\n    \"clean\": \"rimraf lib dist es coverage\",\n    \"lint\": \"eslint src test build\",\n    \"test\": \"cross-env BABEL_ENV=commonjs jest\",\n    \"test:watch\": \"yarn test -- --watch\",\n    \"test:cov\": \"yarn test -- --coverage\",\n    \"coveralls\": \"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls\",\n    \"build:commonjs\": \"cross-env BABEL_ENV=commonjs babel src --out-dir lib\",\n    \"build:es\": \"cross-env BABEL_ENV=es babel src --out-dir es\",\n    \"build:umd\": \"cross-env BABEL_ENV=es NODE_ENV=development rollup -c -i src/index.js -o dist/redux.js\",\n    \"build:umd:min\": \"cross-env BABEL_ENV=es NODE_ENV=production rollup -c -i src/index.js -o dist/redux.min.js\",\n    \"build\": \"yarn run build:commonjs && yarn run build:es && yarn run build:umd && yarn run build:umd:min\",\n    \"prepare\": \"yarn run clean && yarn run lint && yarn test && yarn run build\",\n    \"examples:lint\": \"eslint examples\",\n    \"examples:test\": \"cross-env CI=true babel-node examples/testAll.js\",\n    \"docs:clean\": \"rimraf _book\",\n    \"docs:prepare\": \"gitbook install\",\n    \"docs:build\": \"yarn run docs:prepare && gitbook build -g viniciusdacal/redux-arc && cp logo/apple-touch-icon.png _book/gitbook/images/apple-touch-icon-precomposed-152.png && cp logo/favicon.ico _book/gitbook/images\",\n    \"docs:watch\": \"yarn run docs:prepare && gitbook serve\",\n    \"docs:publish\": \"yarn run docs:clean && yarn run docs:build && cp CNAME _book && cd _book && git init && git commit --allow-empty -m 'update book' && git checkout -b gh-pages && touch .nojekyll && git add . && git commit -am 'update book' && git push git@github.com:viniciusdacal/redux-arc gh-pages --force\"\n  },\n  \"devDependencies\": {\n    \"babel-cli\": \"6.26.0\",\n    \"babel-core\": \"6.26.0\",\n    \"babel-eslint\": \"8.2.2\",\n    \"babel-jest\": \"22.4.1\",\n    \"babel-plugin-external-helpers\": \"6.22.0\",\n    \"babel-plugin-transform-object-rest-spread\": \"6.26.0\",\n    \"babel-preset-env\": \"1.6.1\",\n    \"babel-register\": \"6.26.0\",\n    \"cross-env\": \"5.1.0\",\n    \"eslint\": \"4.9.0\",\n    \"eslint-config-react-app\": \"2.0.1\",\n    \"eslint-plugin-flowtype\": \"2.39.1\",\n    \"eslint-plugin-import\": \"2.2.0\",\n    \"eslint-plugin-jsx-a11y\": \"5.1.1\",\n    \"eslint-plugin-react\": \"7.4.0\",\n    \"gitbook-cli\": \"2.3.2\",\n    \"glob\": \"7.1.1\",\n    \"jest\": \"22.4.2\",\n    \"prettier\": \"1.8.2\",\n    \"redux\": \"3.7.1\",\n    \"rimraf\": \"2.6.2\",\n    \"rollup\": \"0.51.8\",\n    \"rollup-plugin-babel\": \"3.0.2\",\n    \"rollup-plugin-node-resolve\": \"3.0.0\",\n    \"rollup-plugin-replace\": \"2.0.0\",\n    \"rollup-plugin-uglify\": \"2.0.1\"\n  },\n  \"authors\": [\n    \"Vinicius Dacal <viniciusldacal@gmail.com> (https://github.com/viniciusdacal)\"\n  ],\n  \"license\": \"MIT\",\n  \"jest\": {\n    \"coverageDirectory\": \"./coverage\",\n    \"testRegex\": \"(/test/.*\\\\.spec.js)$\",\n    \"globals\": {\n      \"BABEL_ENV\": \"commonjs\"\n    },\n    \"modulePathIgnorePatterns\": [\n      \"<rootDir>/_book/\"\n    ]\n  },\n  \"dependencies\": {},\n  \"peerDependencies\": {\n    \"redux\": \">= 3.7.1\"\n  }\n}\n"
  },
  {
    "path": "redux-arc.sublime-project",
    "content": "{\n\t\"folders\":\n\t[\n\t\t{\n\t\t\t\"path\": \".\"\n\t\t}\n\t],\n  \"build_systems\":\n  [\n    {\n      \"name\": \"Jest\",\n      \"shell_cmd\": \"jest --colors $file\",\n      \"selector\": \"source.js\",\n      \"file_regex\": \".*.(spec|stories).js(?x)\",\n      \"target\": \"ansi_color_build\",\n      \"syntax\": \"Packages/ANSIescape/ANSI.tmLanguage\"\n    }\n  ]\n}\n"
  },
  {
    "path": "redux-arc.sublime-workspace",
    "content": "{\n\t\"auto_complete\":\n\t{\n\t\t\"selected_items\":\n\t\t[\n\t\t\t[\n\t\t\t\t\"midd\",\n\t\t\t\t\"middleware\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"appl\",\n\t\t\t\t\"applyPoint\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"sele\",\n\t\t\t\t\"selected\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"new\",\n\t\t\t\t\"newState\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"selec\",\n\t\t\t\t\"selectedIsLoading\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"en\",\n\t\t\t\t\"ensureValueKey\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"medi\",\n\t\t\t\t\"mediaFiles\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"total\",\n\t\t\t\t\"totalValues\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"ang\",\n\t\t\t\t\"angulo_hora\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"hora\",\n\t\t\t\t\"hora_base_12\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"filt\",\n\t\t\t\t\"filters\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"input\",\n\t\t\t\t\"inputText\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"cach\",\n\t\t\t\t\"cachedBrands\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"rena\",\n\t\t\t\t\"renameKey\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"meta\",\n\t\t\t\t\"metaCached\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"arra\",\n\t\t\t\t\"arrayOf\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"update\",\n\t\t\t\t\"updateStoreValue\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"clien\",\n\t\t\t\t\"clientId\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"fiel\",\n\t\t\t\t\"fieldId\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"categ\",\n\t\t\t\t\"categoryIds\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"cage\",\n\t\t\t\t\"categoryIds\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"In\",\n\t\t\t\t\"instance\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"list\",\n\t\t\t\t\"listResult\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"job\",\n\t\t\t\t\"jobTypes\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"inf\",\n\t\t\t\t\"influencerClass\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"in\",\n\t\t\t\t\"influencerClass\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"chan\",\n\t\t\t\t\"channelsCPM\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"place\",\n\t\t\t\t\"placementId\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"set\",\n\t\t\t\t\"setInfluencerOverride\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"INfluen\",\n\t\t\t\t\"influencerClasses\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"CPm\",\n\t\t\t\t\"CPMs\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"influ\",\n\t\t\t\t\"influencerOverride\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"infl\",\n\t\t\t\t\"influencer\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"campa\",\n\t\t\t\t\"campaignId\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"media\",\n\t\t\t\t\"mediaPlanId\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"opp\",\n\t\t\t\t\"oppId\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"oppo\",\n\t\t\t\t\"opportunityId\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"ac\",\n\t\t\t\t\"action\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"READ\",\n\t\t\t\t\"READ_INITIAL_STATE\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"peding\",\n\t\t\t\t\"pending\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"branc\",\n\t\t\t\t\"branchKey\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"val\",\n\t\t\t\t\"valueKey\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"disab\",\n\t\t\t\t\"disablePreview\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"default\",\n\t\t\t\t\"defaultProps\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"proP\",\n\t\t\t\t\"propTypes\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"sto\",\n\t\t\t\t\"stories\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"boo\",\n\t\t\t\t\"boolean\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"ge\",\n\t\t\t\t\"generateProps\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"has\",\n\t\t\t\t\"hasId\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"UITa\",\n\t\t\t\t\"UITableHCol\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"read\",\n\t\t\t\t\"readResult\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"assin\",\n\t\t\t\t\"assignedToId\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"date\",\n\t\t\t\t\"dateRange\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"onChang\",\n\t\t\t\t\"onChangeCallback\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"defaul\",\n\t\t\t\t\"defaultProps\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"Bool\",\n\t\t\t\t\"BooleanDisplay\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"fetc\",\n\t\t\t\t\"fetchStudios\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"select\",\n\t\t\t\t\"selectorId\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"pased\",\n\t\t\t\t\"parsedNextUrlParams\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"is\",\n\t\t\t\t\"isequal\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"defau\",\n\t\t\t\t\"defaultValues\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"pagina\",\n\t\t\t\t\"paginationKey\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"defa\",\n\t\t\t\t\"defaultValues\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"sor\",\n\t\t\t\t\"sort\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"par\",\n\t\t\t\t\"parsePageToSkip\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"excel\",\n\t\t\t\t\"excelExport\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"pagin\",\n\t\t\t\t\"paginationKey\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"page\",\n\t\t\t\t\"parsePageToSkip\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"previ\",\n\t\t\t\t\"previousValues\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"com\",\n\t\t\t\t\"component\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"MEdia\",\n\t\t\t\t\"MediaValueCalculator\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"onLI\",\n\t\t\t\t\"onListResponse\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"crea\",\n\t\t\t\t\"creators\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"value\",\n\t\t\t\t\"valueKey\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"valu\",\n\t\t\t\t\"valueKey\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"change\",\n\t\t\t\t\"changeSkip\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"create\",\n\t\t\t\t\"createActions\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"creat\",\n\t\t\t\t\"createActions\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"add\",\n\t\t\t\t\"addCustomSearch\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"ADD\",\n\t\t\t\t\"ADD_CUSTOM_SEARCH\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"hand\",\n\t\t\t\t\"handlers\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"handl\",\n\t\t\t\t\"handlerKey\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"type\",\n\t\t\t\t\"typeof\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"param\",\n\t\t\t\t\"paramType\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"INT\",\n\t\t\t\t\"INVALID_ACTION\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"fina\",\n\t\t\t\t\"finalMeta\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"conf\",\n\t\t\t\t\"configPayload\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"actio\",\n\t\t\t\t\"action\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"RESET\",\n\t\t\t\t\"RESET_WITH_META\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"pu\",\n\t\t\t\t\"publicNames\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"Val\",\n\t\t\t\t\"validateConfig\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"va\",\n\t\t\t\t\"validateConfig\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"action\",\n\t\t\t\t\"actionCreatorFactory\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"parse\",\n\t\t\t\t\"parseUrl\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"_\",\n\t\t\t\t\"_REQUEST\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"pars\",\n\t\t\t\t\"parseOptions\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"BASE\",\n\t\t\t\t\"BASE_TYPES\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"names\",\n\t\t\t\t\"NAMESPACE\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"chil\",\n\t\t\t\t\"child\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"sort\",\n\t\t\t\t\"sortOrder\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"spli\",\n\t\t\t\t\"splitSort\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"spl\",\n\t\t\t\t\"splitSort\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"prop\",\n\t\t\t\t\"propTypes\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"clas\",\n\t\t\t\t\"classnames\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"defua\",\n\t\t\t\t\"defaultReturn\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"user\",\n\t\t\t\t\"userId\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"ad\",\n\t\t\t\t\"additionalContactIds\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"id\",\n\t\t\t\t\"idToString\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"find\",\n\t\t\t\t\"findOne\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"capta\",\n\t\t\t\t\"capitalize\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"cap\",\n\t\t\t\t\"capitalize\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"rol\",\n\t\t\t\t\"roleOptions\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"so\",\n\t\t\t\t\"sortBy\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"UITab\",\n\t\t\t\t\"UITableFilters\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"url\",\n\t\t\t\t\"urlParams\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"onChange\",\n\t\t\t\t\"onChangePaginator\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"User\",\n\t\t\t\t\"UserList\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"las\",\n\t\t\t\t\"lastAccess\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"last\",\n\t\t\t\t\"lastName\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"UITable\",\n\t\t\t\t\"UITableHCol\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"UItable\",\n\t\t\t\t\"UITableHeader\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"paed\",\n\t\t\t\t\"parsedValue\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"vel\",\n\t\t\t\t\"velcroHandlers\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"sche\",\n\t\t\t\t\"schemaSelector\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"get\",\n\t\t\t\t\"getUrlParams\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"res\",\n\t\t\t\t\"restFilters\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"se\",\n\t\t\t\t\"schemaSelector\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"debo\",\n\t\t\t\t\"debounce\"\n\t\t\t]\n\t\t]\n\t},\n\t\"buffers\":\n\t[\n\t],\n\t\"build_system\": \"\",\n\t\"build_system_choices\":\n\t[\n\t\t[\n\t\t\t[\n\t\t\t\t[\n\t\t\t\t\t\"Jest\",\n\t\t\t\t\t\"\"\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t\"Packages/ESLint/ESLint.sublime-build\",\n\t\t\t\t\t\"\"\n\t\t\t\t]\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"Jest\",\n\t\t\t\t\"\"\n\t\t\t]\n\t\t],\n\t\t[\n\t\t\t[\n\t\t\t\t[\n\t\t\t\t\t\"Packages/C++/C++ Single File.sublime-build\",\n\t\t\t\t\t\"\"\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t\"Packages/C++/C++ Single File.sublime-build\",\n\t\t\t\t\t\"Run\"\n\t\t\t\t]\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"Packages/C++/C++ Single File.sublime-build\",\n\t\t\t\t\"\"\n\t\t\t]\n\t\t]\n\t],\n\t\"build_varint\": \"\",\n\t\"command_palette\":\n\t{\n\t\t\"height\": 392.0,\n\t\t\"last_filter\": \"close\",\n\t\t\"selected_items\":\n\t\t[\n\t\t\t[\n\t\t\t\t\"close\",\n\t\t\t\t\"File: Close All\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"babel\",\n\t\t\t\t\"Set Syntax: JavaScript (Babel)\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"bl\",\n\t\t\t\t\"Git Blame\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"cop\",\n\t\t\t\t\"File: Copy Path From Project\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"Gutter\",\n\t\t\t\t\"Preferences: GitGutter Settings\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"instal\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"du\",\n\t\t\t\t\"File: Duplicate\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"rub\",\n\t\t\t\t\"Set Syntax: Ruby\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"rena\",\n\t\t\t\t\"File: Rename\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"esli\",\n\t\t\t\t\"ESLint\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"java\",\n\t\t\t\t\"Set Syntax: Java\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"low\",\n\t\t\t\t\"Convert Case: Lower Case\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"eslin\",\n\t\t\t\t\"ESLint\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"eslint\",\n\t\t\t\t\"ESLint\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"b\",\n\t\t\t\t\"Git Blame\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"lowe\",\n\t\t\t\t\"Convert Case: Lower Case\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"install\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"cloe\",\n\t\t\t\t\"Convert Case: Lower Case\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"up\",\n\t\t\t\t\"Convert Case: Upper Case\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"upp\",\n\t\t\t\t\"Convert Case: Upper Case\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"dif\",\n\t\t\t\t\"Diffy Compare\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"insta\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"sor\",\n\t\t\t\t\"Sort Lines\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"m\",\n\t\t\t\t\"Set Syntax: Markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"move\",\n\t\t\t\t\"File: Move\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mo\",\n\t\t\t\t\"File: Move\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"dele\",\n\t\t\t\t\"File: Delete\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"jes\",\n\t\t\t\t\"Build With: Jest\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"remove\",\n\t\t\t\t\"Package Control: Remove Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"build\",\n\t\t\t\t\"Build With: Jest\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"isnta\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"c++\",\n\t\t\t\t\"Build With: C++ Single File\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"run\",\n\t\t\t\t\"Build With: C++ Single File - Run\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"termina\",\n\t\t\t\t\"Terminal View: Open Bash Terminal\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"increment\",\n\t\t\t\t\"Emmet: Increment Number by 1\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"case\",\n\t\t\t\t\"Convert Case: Swap Case\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"reve\",\n\t\t\t\t\"File: Reveal\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"new\",\n\t\t\t\t\"File: New File Relative to Current View\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"copy\",\n\t\t\t\t\"File: Copy Path\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"dupl\",\n\t\t\t\t\"File: Duplicate\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"html\",\n\t\t\t\t\"HTML: Encode Special Characters\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"new file\",\n\t\t\t\t\"File: New File Relative to Current View\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"jsx\",\n\t\t\t\t\"Pretty JSON: JSON 2 XML\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"bla\",\n\t\t\t\t\"Git Blame\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"json\",\n\t\t\t\t\"Pretty JSON: Format (Pretty Print) JSON\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"jspon\",\n\t\t\t\t\"Pretty JSON: Format (Pretty Print) JSON\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mv\",\n\t\t\t\t\"File: Move\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"cp\",\n\t\t\t\t\"File: Copy Path\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"sort\",\n\t\t\t\t\"Pretty JSON: Format and Sort JSON\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"dupli\",\n\t\t\t\t\"File: Duplicate\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"dus\",\n\t\t\t\t\"Plugin Development: Convert Syntax to .sublime-syntax\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"ren\",\n\t\t\t\t\"File: Rename\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"save\",\n\t\t\t\t\"File: Save All\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"clos\",\n\t\t\t\t\"File: Close All\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mark\",\n\t\t\t\t\"Set Syntax: Markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"babe\",\n\t\t\t\t\"Set Syntax: JavaScript (Babel)\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"de\",\n\t\t\t\t\"File: Delete\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"sa\",\n\t\t\t\t\"File: Save All\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"renam\",\n\t\t\t\t\"File: Rename\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"BL\",\n\t\t\t\t\"Git Blame\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"cl\",\n\t\t\t\t\"File: Close All\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"bab\",\n\t\t\t\t\"Set Syntax: JavaScript (Babel)\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"diff\",\n\t\t\t\t\"Set Syntax: Diff\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"theme\",\n\t\t\t\t\"UI: Select Theme\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"disa\",\n\t\t\t\t\"SublimeLinter: Disable Linter\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"bba\",\n\t\t\t\t\"Set Syntax: JavaScript (Babel)\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"babl\",\n\t\t\t\t\"Babel Transform\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"valida\",\n\t\t\t\t\"Pretty JSON: Validate\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"j\",\n\t\t\t\t\"Pretty JSON: JSON query with ./jq\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"jq\",\n\t\t\t\t\"Pretty JSON: JSON query with ./jq\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"es\",\n\t\t\t\t\"Set Syntax: Perl\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"\",\n\t\t\t\t\"ESLint\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mar\",\n\t\t\t\t\"Set Syntax: Markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"clo\",\n\t\t\t\t\"File: Close All\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"blam\",\n\t\t\t\t\"Git Blame\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"rnea\",\n\t\t\t\t\"File: Rename\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"esl\",\n\t\t\t\t\"ESLint\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"re\",\n\t\t\t\t\"File: Rename\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"upper\",\n\t\t\t\t\"Convert Case: Upper Case\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"prettier\",\n\t\t\t\t\"JsPrettier: Format JavaScript\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"remove p\",\n\t\t\t\t\"Package Control: Remove Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"dee\",\n\t\t\t\t\"File: Delete\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mvoe\",\n\t\t\t\t\"File: Move\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"co\",\n\t\t\t\t\"File: Copy Path\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"del\",\n\t\t\t\t\"File: Delete\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"rea\",\n\t\t\t\t\"File: Rename\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"duplic\",\n\t\t\t\t\"File: Duplicate\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"import\",\n\t\t\t\t\"ImportJS: goto module\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"title\",\n\t\t\t\t\"Convert Case: Title Case\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"Convert\",\n\t\t\t\t\"Convert Case: Title Case\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"ja\",\n\t\t\t\t\"Pretty JSON: Format and Sort JSON\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"pretti\",\n\t\t\t\t\"JsPrettier: Format JavaScript\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"jsn\",\n\t\t\t\t\"Pretty JSON: Format and Sort JSON\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"copo\",\n\t\t\t\t\"File: Copy Path From Project\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"path\",\n\t\t\t\t\"File: Copy Path\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"less\",\n\t\t\t\t\"Set Syntax: LESS\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"update\",\n\t\t\t\t\"Package Control: Upgrade/Overwrite All Packages\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"Snippet\",\n\t\t\t\t\"Snippet: Function\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"react cm\",\n\t\t\t\t\"Snippet: React: wrap in a component\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"lorem\",\n\t\t\t\t\"LoremIpsum: (15) some\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"inst\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"post\",\n\t\t\t\t\"Set Syntax: PostCSS\"\n\t\t\t]\n\t\t],\n\t\t\"width\": 436.0\n\t},\n\t\"console\":\n\t{\n\t\t\"height\": 290.0,\n\t\t\"history\":\n\t\t[\n\t\t\t\"cd ~/ben\"\n\t\t]\n\t},\n\t\"distraction_free\":\n\t{\n\t\t\"menu_visible\": true,\n\t\t\"show_minimap\": false,\n\t\t\"show_open_files\": false,\n\t\t\"show_tabs\": false,\n\t\t\"side_bar_visible\": false,\n\t\t\"status_bar_visible\": false\n\t},\n\t\"expanded_folders\":\n\t[\n\t\t\"/Users/viniciusdacal/github/redux-arc\"\n\t],\n\t\"file_history\":\n\t[\n\t\t\"/Users/viniciusdacal/github/redux-arc/test/requestMiddlewares.spec.js\",\n\t\t\"/Users/viniciusdacal/github/redux-arc/test/middlewareWithRedux.spec.js\",\n\t\t\"/Users/viniciusdacal/github/redux-arc/redux-arc.sublime-project\",\n\t\t\"/Users/viniciusdacal/github/redux-arc/docs/advanced/RequestMiddlewares.md\",\n\t\t\"/Users/viniciusdacal/github/redux-arc/src/requestMiddlewares.js\",\n\t\t\"/Users/viniciusdacal/github/redux-arc/README.md\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Tools/MediaValueCalculator/AdditionalFields/AdditionalFields.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Tools/MediaValueCalculator/MediaValueCalculator.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Tools/MediaValueCalculator/connector.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Placement/reducers.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/Input/Input.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/Input/Number/Number.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/Input/Currency/Currency.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Tools/MediaValueCalculator/MediaValueCalculator.scss\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Tools/MediaValueCalculator/Calculations/Calculations.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/js/components/content/opportunities/form/form.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/js/components/content/opportunities/form/form.jade\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/store/api/errorHandlers.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/Form/Form.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/Form/connector.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/store/middlewares/redirectOnResponse.js\",\n\t\t\"/Users/viniciusdacal/ben/app/api/packages/media-plans/lib/permissions.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/reducers.js\",\n\t\t\"/Users/viniciusdacal/ben/app/api/packages/users/lib/handlers.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Opportunity/Filter/Channel/Channel.stories.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Opportunity/Filter/Channel/Channel.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Opportunity/Filter/Channel/utils/helpers.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/Selector/Selector.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/utils/reduxSelector/reduxSelector.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/reduxFormField/reduxFormField.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/utils/reduxSelector/actions.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/scss/components/_close.scss\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Brand/Selector/Selector.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/utils/reduxSelector/reducers.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/utils/reduxSelector/selectors.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/utils/reduxSelector/createSelectors.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Brand/Form/Form.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/utils/function.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/js/app/common/directives/react-file-uploader.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/Uploader/connector.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/View/Totals/Totals.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/View/View.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/View/Summary/Summary.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/View/connector.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/View/Channels/Channels.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/Card/Card.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/UI/ActionIconList/Item/Item.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/.eslintrc\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/selectors.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Opportunity/Search/Filters/connector.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Opportunity/Content/Filters/connector.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Opportunity/Content/Filters/Filters.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Placement/View/connector.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/Report/connector.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/e2e-tests/support/api.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/js/app/opportunity/directives/inline-view.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Opportunity/Search/connector.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Persona/Form/Form.stories.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/Uploader/UploadedFile/UploadedFile.stories.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/User/Form/AccountInfo/AccountInfo.stories.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/__mocks__/redux-form.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/Select/ButtonGroup/ButtonGroup.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/Selector/Selector.stories.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Opportunity/ChannelsAlertsAndRatings/ChannelsAlertsAndRatings.stories.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Opportunity/ChannelsAlertsAndRatings/ChannelsAlertsAndRatings.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Opportunity/Filter/Ratings/Ratings.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/User/Form/AccountInfo/AccountInfo.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/FilteredList/Filters/Filters.stories.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/Search/Search.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/FilteredList/Filters/Filters.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/.storybook/config.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/Selector/Filters/Filters.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/Selector/Filters/Filters.stories.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/.storybook/webpack.config.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/config/jest/setup.js\",\n\t\t\"/Users/viniciusdacal/ben/app/package.json\",\n\t\t\"/Users/viniciusdacal/ben/app/web/package.json\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/CountrySelector/CountrySelector.stories.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/Uploader/Dropzone/Dropzone.stories.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/Uploader/UploadedFile/UploadedFile.spec.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Opportunity/StatusAndCoordinators/StatusAndCoordinators.stories.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/vagrant/config.rb\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/QueuedJobs/reducers.spec.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/QueuedJobs/List/List.stories.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/ButtonGroup/ButtonGroup.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/QueuedJobs/utils/mockedData.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/DatePicker/DatePicker.stories.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/DatePicker/DatePicker.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/QueuedJobs/reducers.js\",\n\t\t\"/Users/viniciusdacal/ben/app/vagrant/config.rb.dist\",\n\t\t\"/Users/viniciusdacal/ben/app/vagrant/README.md\",\n\t\t\"/Users/viniciusdacal/ben/app/web/.babelrc\",\n\t\t\"/Users/viniciusdacal/Library/Application Support/Sublime Text 3/Packages/User/ESLint.sublime-settings\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Route/Private/Private.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/QueuedJobs/List/List.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/AllocatedUsages/QualitySelector/QualitySelector.stories.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/AllocatedUsages/QualitySelector/QualitySelector.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Client/Selector/Selector.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/User/Form/ClientAndBrands.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Brand/Form/connector.js\",\n\t\t\"/Users/viniciusdacal/ben/ben.sublime-project\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/store/settings/actions.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/store/reduxForm.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/config/webpack.base.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/store/history/history.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/public/index.html\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/Form/utils.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/config/webpack.prod.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/config/webpack.dll.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/TimePicker/connector.spec.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/TimePicker/connector.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/DateRangePicker/DateRangePicker.stories.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/DateRangePicker/DateRangePicker.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Placement/View/View.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Placement/View/chunks/Header.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Placement/View/Header/Header.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Opportunity/Search/Filters/Filters.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Opportunity/utils/withMediaPlanFilters.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/Top/Top.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/FilteredList/FilteredList.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/MediaPlan/Form/defaultValuesBuilder.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/utils/fieldsSchema/fieldsSchema.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Placement/View/Header/Header.scss\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/Form/DatePicker/scss/datepicker-styles.scss\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/QueuedJobs/List/schema.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/components/User/List/connector.jsx\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/utils/filtersWithUrl/selectors.js\",\n\t\t\"/Users/viniciusdacal/ben/app/web/src/utils/filtersWithUrl/filtersWithUrl.js\"\n\t],\n\t\"find\":\n\t{\n\t\t\"height\": 157.0\n\t},\n\t\"find_in_files\":\n\t{\n\t\t\"height\": 111.0,\n\t\t\"where_history\":\n\t\t[\n\t\t]\n\t},\n\t\"find_state\":\n\t{\n\t\t\"case_sensitive\": true,\n\t\t\"find_history\":\n\t\t[\n\t\t\t\"payload:\",\n\t\t\t\"payload\",\n\t\t\t\"jest\",\n\t\t\t\"middlewares\",\n\t\t\t\"police\",\n\t\t\t\"middlewares\",\n\t\t\t\"exists\",\n\t\t\t\"item\"\n\t\t],\n\t\t\"highlight\": true,\n\t\t\"in_selection\": false,\n\t\t\"preserve_case\": false,\n\t\t\"regex\": false,\n\t\t\"replace_history\":\n\t\t[\n\t\t],\n\t\t\"reverse\": false,\n\t\t\"show_context\": true,\n\t\t\"use_buffer2\": true,\n\t\t\"whole_word\": false,\n\t\t\"wrap\": true\n\t},\n\t\"groups\":\n\t[\n\t\t{\n\t\t\t\"sheets\":\n\t\t\t[\n\t\t\t]\n\t\t}\n\t],\n\t\"incremental_find\":\n\t{\n\t\t\"height\": 25.0\n\t},\n\t\"input\":\n\t{\n\t\t\"height\": 84.0\n\t},\n\t\"layout\":\n\t{\n\t\t\"cells\":\n\t\t[\n\t\t\t[\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\t1,\n\t\t\t\t1\n\t\t\t]\n\t\t],\n\t\t\"cols\":\n\t\t[\n\t\t\t0.0,\n\t\t\t1.0\n\t\t],\n\t\t\"rows\":\n\t\t[\n\t\t\t0.0,\n\t\t\t1.0\n\t\t]\n\t},\n\t\"menu_visible\": true,\n\t\"output.SublimeLinter\":\n\t{\n\t\t\"height\": 0.0\n\t},\n\t\"output.exec\":\n\t{\n\t\t\"height\": 176.0\n\t},\n\t\"output.find_results\":\n\t{\n\t\t\"height\": 0.0\n\t},\n\t\"output.mdpopups\":\n\t{\n\t\t\"height\": 0.0\n\t},\n\t\"output.unsaved_changes\":\n\t{\n\t\t\"height\": 112.0\n\t},\n\t\"pinned_build_system\": \"\",\n\t\"project\": \"redux-arc.sublime-project\",\n\t\"replace\":\n\t{\n\t\t\"height\": 46.0\n\t},\n\t\"save_all_on_build\": true,\n\t\"select_file\":\n\t{\n\t\t\"height\": 0.0,\n\t\t\"last_filter\": \"\",\n\t\t\"selected_items\":\n\t\t[\n\t\t\t[\n\t\t\t\t\"request\",\n\t\t\t\t\"docs/advanced/RequestMiddlewares.md\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"placement/redu\",\n\t\t\t\t\"web/src/components/Placement/reducers.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediavaluecalcula\",\n\t\t\t\t\"web/src/components/Tools/MediaValueCalculator/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"additionalfields\",\n\t\t\t\t\"web/src/components/Tools/MediaValueCalculator/AdditionalFields/AdditionalFields.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"inputcurrency\",\n\t\t\t\t\"web/src/components/Form/Input/Currency/Currency.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"inputnumber\",\n\t\t\t\t\"web/src/components/Form/Input/Number/Number.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"forminput\",\n\t\t\t\t\"web/src/components/Form/Input/Input.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"calculations\",\n\t\t\t\t\"web/src/components/Tools/MediaValueCalculator/Calculations/Calculations.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediavalue\",\n\t\t\t\t\"web/src/components/Tools/MediaValueCalculator/MediaValueCalculator.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"redire\",\n\t\t\t\t\"web/src/store/middlewares/redirectOnResponse.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mp/form/conn\",\n\t\t\t\t\"web/src/components/MediaPlan/Form/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediaplanform\",\n\t\t\t\t\"web/src/components/MediaPlan/Form/Form.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"errorhand\",\n\t\t\t\t\"web/src/store/api/errorHandlers.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mp/redu\",\n\t\t\t\t\"web/src/components/MediaPlan/reducers.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"users/han\",\n\t\t\t\t\"api/packages/users/lib/handlers.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"opportunityfilterchannel\",\n\t\t\t\t\"web/src/components/Opportunity/Filter/Channel/Channel.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"opportunityfilterchanne\",\n\t\t\t\t\"web/src/components/Opportunity/Filter/Channel/Channel.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"reduxsele\",\n\t\t\t\t\"web/src/utils/reduxSelector/reduxSelector.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"formselector.jsx\",\n\t\t\t\t\"web/src/components/Form/Selector/Selector.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"reduxformfi\",\n\t\t\t\t\"web/src/components/Form/reduxFormField/reduxFormField.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"opp/filterchann\",\n\t\t\t\t\"web/src/components/Opportunity/Filter/Channel/Channel.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"close\",\n\t\t\t\t\"web/scss/components/_close.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"brandselector\",\n\t\t\t\t\"web/src/components/Brand/Selector/Selector.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"utils/reduxselector/createselectors\",\n\t\t\t\t\"web/src/utils/reduxSelector/createSelectors.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"reduxselector/sele\",\n\t\t\t\t\"web/src/utils/reduxSelector/selectors.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"reduxselectorac\",\n\t\t\t\t\"web/src/utils/reduxSelector/actions.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mpform/conne\",\n\t\t\t\t\"web/src/components/MediaPlan/Form/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"reduxselector/reduc\",\n\t\t\t\t\"web/src/utils/reduxSelector/reducers.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediaplanform/con\",\n\t\t\t\t\"web/src/components/MediaPlan/Form/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"brandform\",\n\t\t\t\t\"web/src/components/Brand/Form/Form.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"components/form/uploader/connector\",\n\t\t\t\t\"web/src/components/Form/Uploader/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"react-uplo\",\n\t\t\t\t\"web/js/app/common/directives/react-file-uploader.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"actioniconlistitem\",\n\t\t\t\t\"web/src/components/UI/ActionIconList/Item/Item.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediaplancard\",\n\t\t\t\t\"web/src/components/MediaPlan/Card/Card.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediaplanviewchannels\",\n\t\t\t\t\"web/src/components/MediaPlan/View/Channels/Channels.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"summary.jsx\",\n\t\t\t\t\"web/src/components/MediaPlan/View/Summary/Summary.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"components/mediaplan/selectors\",\n\t\t\t\t\"web/src/components/MediaPlan/selectors.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediaplanview/con\",\n\t\t\t\t\"web/src/components/MediaPlan/View/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediaplanview\",\n\t\t\t\t\"web/src/components/MediaPlan/View/View.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediaplanviewtot\",\n\t\t\t\t\"web/src/components/MediaPlan/View/Totals/Totals.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mp/reduc\",\n\t\t\t\t\"web/src/components/MediaPlan/reducers.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"api.j\",\n\t\t\t\t\"web/e2e-tests/support/api.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediaplanview/\",\n\t\t\t\t\"web/src/components/MediaPlan/View/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"channels\",\n\t\t\t\t\"web/src/components/MediaPlan/View/Channels/Channels.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"src/__mocks__/redux-form.jsx\",\n\t\t\t\t\"web/src/__mocks__/redux-form.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"user/form/accountinfo/accountinfo.stories.jsx\",\n\t\t\t\t\"web/src/components/User/Form/AccountInfo/AccountInfo.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"uploader/uploadedfile/uploadedfile.stories.jsx\",\n\t\t\t\t\"web/src/components/Form/Uploader/UploadedFile/UploadedFile.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"src/components/form/select/buttongroup/buttongroup.jsx\",\n\t\t\t\t\"web/src/components/Form/Select/ButtonGroup/ButtonGroup.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"components/persona/form/form.stories.jsx\",\n\t\t\t\t\"web/src/components/Persona/Form/Form.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediaplanlistfilters\",\n\t\t\t\t\"web/src/components/MediaPlan/FilteredList/Filters/Filters.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"filteredlist/filters/filters.stories.jsx\",\n\t\t\t\t\"web/src/components/MediaPlan/FilteredList/Filters/Filters.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"form/accountinfo/accountinfo\",\n\t\t\t\t\"web/src/components/User/Form/AccountInfo/AccountInfo.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"components/opportunity/filter/ratings/ratings.jsx\",\n\t\t\t\t\"web/src/components/Opportunity/Filter/Ratings/Ratings.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"oppchannelsalertsandratings\",\n\t\t\t\t\"web/src/components/Opportunity/ChannelsAlertsAndRatings/ChannelsAlertsAndRatings.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"opportunity/channelsalertsandratings/channelsalertsandratings.stories.jsx\",\n\t\t\t\t\"web/src/components/Opportunity/ChannelsAlertsAndRatings/ChannelsAlertsAndRatings.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"components/form/selector/selector.stories.jsx\",\n\t\t\t\t\"web/src/components/Form/Selector/Selector.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"formselectorfilters\",\n\t\t\t\t\"web/src/components/Form/Selector/Filters/Filters.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"src/components/opportunity/statusandcoordinators/statusandcoordinators.stories.jsx\",\n\t\t\t\t\"web/src/components/Opportunity/StatusAndCoordinators/StatusAndCoordinators.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"uploadedfile\",\n\t\t\t\t\"web/src/components/Form/Uploader/UploadedFile/UploadedFile.spec.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"src/components/form/uploader/uploadedfile/uploadedfile.stories.j\",\n\t\t\t\t\"web/src/components/Form/Uploader/UploadedFile/UploadedFile.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"src/components/form/uploader/dropzone/dropzone.stories.jsx\",\n\t\t\t\t\"web/src/components/Form/Uploader/Dropzone/Dropzone.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"src/components/form/selector/selector.stories.jsx\",\n\t\t\t\t\"web/src/components/Form/Selector/Selector.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"src/components/form/countryselector/countryselector.stories.jsx\",\n\t\t\t\t\"web/src/components/Form/CountrySelector/CountrySelector.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"package.json\",\n\t\t\t\t\"web/package.json\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"config/jest/setup.js\",\n\t\t\t\t\"web/config/jest/setup.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"storybook/webpack.config.js\",\n\t\t\t\t\"web/.storybook/webpack.config.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\".storybook/config.js\",\n\t\t\t\t\"web/.storybook/config.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"src/components/queuedjobs/list/list.stories.jsx\",\n\t\t\t\t\"web/src/components/QueuedJobs/List/List.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"web/src/components/form/buttongroup/buttongroup.jsx\",\n\t\t\t\t\"web/src/components/Form/ButtonGroup/ButtonGroup.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"queuedjobs/utils/mockeddata.js\",\n\t\t\t\t\"web/src/components/QueuedJobs/utils/mockedData.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"components/queuedjobs/list/list.stories.jsx\",\n\t\t\t\t\"web/src/components/QueuedJobs/List/List.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"datepicker\",\n\t\t\t\t\"web/src/components/Form/DatePicker/DatePicker.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"datepicker/datepicker.stories.jsx\",\n\t\t\t\t\"web/src/components/Form/DatePicker/DatePicker.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"components/queuedjobs/reducers.js\",\n\t\t\t\t\"web/src/components/QueuedJobs/reducers.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"components/queuedjobs/reducers.spec.js\",\n\t\t\t\t\"web/src/components/QueuedJobs/reducers.spec.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"web/src/components/mediaplan/form/form.jsx\",\n\t\t\t\t\"web/src/components/MediaPlan/Form/Form.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"omponents/mediaplan/form/connector.js\",\n\t\t\t\t\"web/src/components/MediaPlan/Form/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"buttongroup\",\n\t\t\t\t\"web/src/components/Form/ButtonGroup/ButtonGroup.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"qualityselector\",\n\t\t\t\t\"web/src/components/MediaPlan/AllocatedUsages/QualitySelector/QualitySelector.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediaplan/allocatedusages/qualityselector/qualityselector.stories.jsx\",\n\t\t\t\t\"web/src/components/MediaPlan/AllocatedUsages/QualitySelector/QualitySelector.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"components/queuedjobs/list/list\",\n\t\t\t\t\"web/src/components/QueuedJobs/List/List.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"queutils/mockeddata\",\n\t\t\t\t\"web/src/components/QueuedJobs/utils/mockedData.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"private\",\n\t\t\t\t\"web/src/components/Route/Private/Private.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediaplan/form/connector.j\",\n\t\t\t\t\"web/src/components/MediaPlan/Form/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediaplan/form/form.jsx\",\n\t\t\t\t\"web/src/components/MediaPlan/Form/Form.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"web/src/utils/reduxselector/reducers.js\",\n\t\t\t\t\"web/src/utils/reduxSelector/reducers.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"src/utils/function.js\",\n\t\t\t\t\"web/src/utils/function.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"clientselec\",\n\t\t\t\t\"web/src/components/Client/Selector/Selector.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediaplan/form/co\",\n\t\t\t\t\"web/src/components/MediaPlan/Form/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"clientselector\",\n\t\t\t\t\"web/src/components/Client/Selector/Selector.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"reduselector/\",\n\t\t\t\t\"web/src/utils/reduxSelector/reducers.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"user/form\",\n\t\t\t\t\"web/src/components/User/Form/ClientAndBrands.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"reduxse\",\n\t\t\t\t\"web/src/utils/reduxSelector/reduxSelector.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediaplanform/conne\",\n\t\t\t\t\"web/src/components/MediaPlan/Form/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"brandform/con\",\n\t\t\t\t\"web/src/components/Brand/Form/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"/components/mediaplan/form/connector.js\",\n\t\t\t\t\"web/src/components/MediaPlan/Form/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"redusele\",\n\t\t\t\t\"web/src/utils/reduxSelector/reduxSelector.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"setting/ac\",\n\t\t\t\t\"web/src/store/settings/actions.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediavalu/conn\",\n\t\t\t\t\"web/src/components/Tools/MediaValueCalculator/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"reduxform\",\n\t\t\t\t\"web/src/store/reduxForm.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"histo\",\n\t\t\t\t\"web/src/store/history/history.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mp/form\",\n\t\t\t\t\"web/src/components/MediaPlan/Form/Form.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"timepicker/con\",\n\t\t\t\t\"web/src/components/Form/TimePicker/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"daterangepic\",\n\t\t\t\t\"web/src/components/Form/DateRangePicker/DateRangePicker.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"form/daterangepicker/daterangepicker.stories.jsx\",\n\t\t\t\t\"web/src/components/Form/DateRangePicker/DateRangePicker.stories.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"form/timepicker/connector\",\n\t\t\t\t\"web/src/components/Form/TimePicker/connector.spec.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"store/reduxform\",\n\t\t\t\t\"web/src/store/reduxForm.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mediaplan/filt\",\n\t\t\t\t\"web/src/components/MediaPlan/FilteredList/Filters/Filters.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"withmediaplanfilters\",\n\t\t\t\t\"web/src/components/Opportunity/utils/withMediaPlanFilters.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"opportunity/search/fil\",\n\t\t\t\t\"web/src/components/Opportunity/Search/Filters/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"opportunity/search/filter\",\n\t\t\t\t\"web/src/components/Opportunity/Search/Filters/Filters.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"utils/fieldsschema\",\n\t\t\t\t\"web/src/utils/fieldsSchema/fieldsSchema.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"pl/view/header\",\n\t\t\t\t\"web/src/components/Placement/View/Header/Header.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"placementview\",\n\t\t\t\t\"web/src/components/Placement/View/View.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"components/form/buttongroup/buttongroup.jsx\",\n\t\t\t\t\"web/src/components/Form/ButtonGroup/ButtonGroup.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"opportunity/search/filters/connector.js\",\n\t\t\t\t\"web/src/components/Opportunity/Search/Filters/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"filterswithurls/\",\n\t\t\t\t\"web/src/utils/filtersWithUrl/selectors.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"filterswithurl/\",\n\t\t\t\t\"web/src/utils/filtersWithUrl/utils.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"userlist/cone\",\n\t\t\t\t\"web/src/components/User/List/connector.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"withurl\",\n\t\t\t\t\"web/src/utils/filtersWithUrl/filtersWithUrl.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"groupbutt\",\n\t\t\t\t\"web/src/components/Form/ButtonGroup/ButtonGroup.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"withmed\",\n\t\t\t\t\"web/src/components/Opportunity/utils/withMediaPlanFilters.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"opp/search/filter\",\n\t\t\t\t\"web/src/components/Opportunity/Search/Filters/connector.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"channelsalertsandratings\",\n\t\t\t\t\"web/src/components/Opportunity/ChannelsAlertsAndRatings/ChannelsAlertsAndRatings.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"reduxformfie\",\n\t\t\t\t\"web/src/components/Form/reduxFormField/reduxFormField.jsx\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"filterswithurl\",\n\t\t\t\t\"web/src/utils/filtersWithUrl/selectors.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"filters\",\n\t\t\t\t\"web/src/utils/filtersWithUrl/filtersWithUrl.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"buttongrou\",\n\t\t\t\t\"web/src/components/Form/ButtonGroup/ButtonGroup.jsx\"\n\t\t\t]\n\t\t],\n\t\t\"width\": 0.0\n\t},\n\t\"select_project\":\n\t{\n\t\t\"height\": 0.0,\n\t\t\"last_filter\": \"\",\n\t\t\"selected_items\":\n\t\t[\n\t\t],\n\t\t\"width\": 0.0\n\t},\n\t\"select_symbol\":\n\t{\n\t\t\"height\": 0.0,\n\t\t\"last_filter\": \"\",\n\t\t\"selected_items\":\n\t\t[\n\t\t],\n\t\t\"width\": 0.0\n\t},\n\t\"selected_group\": 0,\n\t\"settings\":\n\t{\n\t},\n\t\"show_minimap\": true,\n\t\"show_open_files\": false,\n\t\"show_tabs\": true,\n\t\"side_bar_visible\": true,\n\t\"side_bar_width\": 301.0,\n\t\"status_bar_visible\": true,\n\t\"template_settings\":\n\t{\n\t}\n}\n"
  },
  {
    "path": "rollup.config.js",
    "content": "import nodeResolve from 'rollup-plugin-node-resolve';\nimport babel from 'rollup-plugin-babel';\nimport replace from 'rollup-plugin-replace';\nimport uglify from 'rollup-plugin-uglify';\n\nvar env = process.env.NODE_ENV\n\nconst config = {\n  input: 'src/index.js',\n  plugins: []\n}\n\nif (env === 'es' || env === 'cjs') {\n  config.output = { format: env }\n  config.external = ['redux']\n  config.plugins.push(\n    babel({\n      plugins: ['external-helpers'],\n    })\n  )\n}\n\nif (env === 'development' || env === 'production') {\n  config.output = { format: 'umd' }\n  config.name = 'ReduxArc'\n  config.plugins.push(\n    nodeResolve({\n      jsnext: true\n    }),\n    babel({\n      exclude: [\n        '**/node_modules/**',\n        'src/__mocks__/**',\n      ],\n      plugins: ['external-helpers'],\n    }),\n    replace({\n      'process.env.NODE_ENV': JSON.stringify(env)\n    })\n  )\n}\n\nif (env === 'production') {\n  config.plugins.push(\n    uglify({\n      compress: {\n        pure_getters: true,\n        unsafe: true,\n        unsafe_comps: true,\n        warnings: false\n      }\n    })\n  )\n}\n\nexport default config\n"
  },
  {
    "path": "src/apiActionCreatorFactory.js",
    "content": "import { toAsyncTypes } from './utils';\nimport parseUrl from './parseUrl';\n\nconst normalizeUrl = (url, params) => typeof url === 'function' ? url(params) : url;\n\nexport default function apiActionCreatorFactory(config, type) {\n  const { payload: configPayload, url: configUrl, meta: configMeta, ...restMeta } = config;\n  const asyncTypes = toAsyncTypes(type);\n\n  function apiActionCreator(payload, meta) {\n    const url = normalizeUrl(configUrl, meta);\n\n    const finalMeta = {\n      ...restMeta,\n      ...(configMeta || {}),\n      ...(meta || {}),\n    };\n\n    return {\n      type: asyncTypes,\n      payload: payload !== undefined ? payload : configPayload,\n      meta: {\n        ...finalMeta,\n        url: parseUrl(url, finalMeta),\n      },\n    };\n  }\n\n  Object.assign(apiActionCreator, config);\n\n  return apiActionCreator;\n}\n"
  },
  {
    "path": "src/createActions.js",
    "content": "import { parseToUppercase } from './utils';\nimport createTypes from './createTypes';\nimport createCreators from './createCreators';\nimport validateConfig from './validateConfig';\nimport toExternalTypes from './toExternalTypes';\n\n/*\n  @param {string} namespace - namespace to be uppercased and prefix your action types\n  @param {Array} config - object with options\n*/\nexport default function createActions(namespace, config) {\n  const NAMESPACE = parseToUppercase(namespace);\n  validateConfig(NAMESPACE, config);\n\n  const actionKeys = Object.keys(config);\n  const actionTypes = createTypes(actionKeys, NAMESPACE);\n  const creators = createCreators(config, actionTypes);\n\n  return {\n    creators,\n    types: toExternalTypes(config, actionTypes),\n  };\n}\n"
  },
  {
    "path": "src/createAsyncMiddleware.js",
    "content": "import { compose } from 'redux';\nimport { checkAction } from './utils';\nimport { getRequestMiddlewares } from './requestMiddlewares';\n\n/**\n* This is a standard Redux middleware that listens for async actions\n* This middleware waits as its first param, a function with the following signature\n* done => (action, response) => done(action, error, response)\n*\n* The actions for this middleware, should look like the following\n*  {\n*    type: ['REQUEST_TYPE', 'RESPONSE_TYPE'],\n*    payload: {},\n*    meta: {\n*      ...allAdditionalData\n*    },\n*  }\n* @param {Object} asyncTask - function that executes the async task\n*/\n\nfunction execAsyncTask(requestType, asyncTask) {\n  return store => next => (action) => {\n    store.dispatch({\n      type: requestType,\n      meta: action.meta,\n      payload: action.payload,\n    });\n\n    const done = (err, response) => next(action, err, response);\n\n    const options = { payload: action.payload, ...action.meta };\n    return asyncTask(store)(done)(options);\n  };\n}\n\nfunction handleResponse(responseType) {\n  return store => (action, err, response) => {\n    const responseAction = {\n      type: responseType,\n      meta: action.meta,\n      payload: response,\n    };\n    if (err) {\n      const actionToDispatch = { ...responseAction, error: true, payload: err };\n      store.dispatch(actionToDispatch);\n      return err;\n    }\n    store.dispatch(responseAction);\n    return response;\n  };\n}\n\nexport default function createAsyncMiddleware(asyncTask) {\n  if (typeof asyncTask !== 'function') {\n    const warning =\n      'You must provide a asyncTask function to createAsyncMiddleware, with the following signature: ';\n    const example = 'done => (action, error, response) => done(action, error, response)';\n    throw new Error(`${warning} \\n ${example}`)\n  }\n\n  return store => next => (action) => {\n    const { type, meta } = action;\n\n    if (!Array.isArray(type)) {\n      return next(action);\n    }\n\n    if (!checkAction(type)) {\n      throw new Error('Expected type to be an array of two strings, request and response.');\n    }\n\n    if (!meta || typeof meta !== 'object') {\n      throw new Error('Expected meta to be an object');\n    }\n\n    const requestMiddlewares = getRequestMiddlewares(action.meta.middlewares);\n    const [requestType, responseType] = action.type;\n\n    const chain = [\n      requestMiddlewares('onRequest'),\n      execAsyncTask(requestType, asyncTask),\n      requestMiddlewares('onResponse'),\n    ].map(middleware => middleware(store));\n\n    const done = handleResponse(responseType)(store);\n    return compose(...chain)(done)(action);\n  };\n}\n"
  },
  {
    "path": "src/createCreators.js",
    "content": "import fsaActionCreatorFactory from './fsaActionCreatorFactory';\nimport apiActionCreatorFactory from './apiActionCreatorFactory';\n\nfunction getFactory(singleConfig) {\n  return !singleConfig || !singleConfig.url\n    ? fsaActionCreatorFactory\n    : apiActionCreatorFactory;\n}\nconst DEFAULT_CONFIG = {};\n\n/*\n  @param {Object} config - original config object provided to createActions\n  @param {Object} actionTypes - action types object with keys being the original names and the value\n  being the uppercased namespace + uppercased name.\n*/\nexport default function createCreators(config, actionTypes) {\n  return Object.keys(config).reduce((acc, creatorName) => {\n    const singleConfig = config[creatorName] || DEFAULT_CONFIG;\n    const factory = getFactory(singleConfig)\n\n    return {\n      ...acc,\n      [creatorName]: factory(singleConfig, actionTypes[creatorName]),\n    };\n  }, {});\n}\n"
  },
  {
    "path": "src/createReducers.js",
    "content": "function insertEmojis (string) {\n  const searches = [\n    ' undefined',\n    ' null',\n    ' \\'',\n    ' \\\\[object Object\\\\]',\n    ' \\[0-9\\].*',\n  ];\n\n  return searches.reduce(\n    (str, search, index) => str.replace(new RegExp(`(${search})`, 'g'), ` 👉$1`), string)\n}\n\nfunction visualValue(value) {\n  if (value === null) return 'null';\n  if (value === undefined) return 'undefined';\n  if (typeof value === 'string') return `'${value}'`;\n  if (typeof value === 'function') {\n    return value.toString().replace(/\\n/g, '').replace(/{(.*)}/g, '{ ... }');\n  }\n  return value;\n}\n\nfunction objToString(obj) {\n  let output = [];\n  Object.keys(obj).forEach((key) => {\n    output.push(`  ${key}: ${visualValue(obj[key])},`);\n  });\n  return `{\\n${output.join('\\n')}\\n}`;\n}\n\nfunction validateHandlers(handlers) {\n  if (!handlers) {\n    throw new Error(`Invalid handler: ${handlers}`);\n  }\n  const isInvalid = Object.keys(handlers).some((key) =>\n    key === '[object Object]' ||\n    key === 'undefined' ||\n    key === 'null' ||\n    typeof handlers[key] !== 'function'\n  );\n\n  if (isInvalid) {\n    throw new Error(\n      `All keys must be valid types and all values should be functions:\\n${insertEmojis(objToString(handlers))}\n    `);\n  }\n}\n\nexport default function createReducers(initialState, handlers) {\n  validateHandlers(handlers);\n\n  return (state = initialState, action) => {\n    if (!action) {\n      return state;\n    }\n\n    const handler = handlers[action.type];\n    return !handler ? state : handler(state, action);\n  }\n}\n"
  },
  {
    "path": "src/createTypes.js",
    "content": "import { parseToUppercase } from './utils';\n\nexport default function createTypes(actionKeys, NAMESPACE) {\n  return actionKeys.reduce((acc, actionName) => ({\n    ...acc,\n    [actionName]: `${NAMESPACE}_${parseToUppercase(actionName)}`,\n  }), {});\n};\n"
  },
  {
    "path": "src/fsaActionCreatorFactory.js",
    "content": "export default function actionCreatorFactory(config, type) {\n  const normalizedConfig = config !== null && typeof config === 'object'\n    ? config\n    : {};\n\n  const { payload: configPayload, meta: configMeta, error: configError } = config;\n\n  function actionCreator(payload, meta, error) {\n    const action = {\n      type,\n    };\n\n    const finalMeta = {\n      ...configMeta,\n      ...meta,\n    };\n\n    if (Object.keys(finalMeta).length) {\n      action.meta = finalMeta;\n    }\n\n    const finalPayload = payload !== undefined\n      ? payload\n      : configPayload;\n\n    if (finalPayload !== undefined) {\n      action.payload = finalPayload;\n    }\n\n    const finalError = error !== undefined\n      ? error\n      : configError;\n\n    if (finalError !== undefined) {\n      action.error = finalError;\n    }\n\n    return action;\n  }\n\n  Object.assign(actionCreator, normalizedConfig);\n\n  return actionCreator;\n}\n"
  },
  {
    "path": "src/index.js",
    "content": "import createActions from './createActions';\nimport createAsyncMiddleware from './createAsyncMiddleware';\nimport createReducers from './createReducers';\nimport middlewares from './requestMiddlewares';\n\nexport {\n  createActions,\n  createAsyncMiddleware,\n  createReducers,\n  middlewares,\n};\n"
  },
  {
    "path": "src/parseUrl.js",
    "content": "export default function parseUrl(url, params) {\n  return url.replace(/(:)([A-Za-z][A-Za-z0-9]*)/g, (match, $1, $2) => {\n    const paramType  = typeof params[$2];\n    if (paramType !== 'string' && paramType !== 'number') {\n      throw new Error(`Param ${$2} from url ${url}, not found in params object`);\n    }\n    return params[$2];\n  });\n}\n"
  },
  {
    "path": "src/requestMiddlewares.js",
    "content": "import { compose } from 'redux';\n\n/**\n* This is a middleware manager, which is used to get get and run middlewares\n* over actions and responses\n*\n* A request middleware should follow the signature below\n* store => done => (action, error, response) => done(action, error, response);\n* A middleware must have an applyPoint property. The available apply points are:\n* 'onRequest' and 'onResponse'\n*/\n\nconst applyPoints = ['onRequest', 'onResponse'];\n\nconst notEmpty = item => !!item;\n\nexport function validateMiddleware(middlewares) {\n  middlewares.forEach(middleware => {\n    if (typeof middleware !== 'function') {\n      throw new Error(`All middlewares should be functions: [${middlewares}]`);\n    }\n\n    if (applyPoints.indexOf(middleware.applyPoint) < 0) {\n      const invalid = `Invalid applyPoint: ${middleware.applyPoint}, provided with middleware: ${middleware.name}.`;\n      const available = `The apply points available are: ${applyPoints.join(', ')}`;\n      throw new Error(`${invalid} ${available}`);\n    }\n  });\n}\n\nconst withApplyPoint = applyPoint => middleware => middleware.applyPoint === applyPoint;\n\nconst get = middlewares => (applyPoint) => {\n  const applyMiddlewares = middlewares.filter(withApplyPoint(applyPoint));\n\n  return store => done => {\n    const chain = applyMiddlewares.map(middleware => middleware(store));\n    return compose(...chain)(done);\n  };\n};\n\nexport function getRequestMiddlewares(middlewares) {\n  if (!Array.isArray(middlewares)) {\n    return get([]);\n  }\n  const actualMiddlewares = middlewares.filter(notEmpty);\n  validateMiddleware(actualMiddlewares);\n\n  return get(actualMiddlewares);\n};\n\nexport default {\n  getRequestMiddlewares,\n};\n"
  },
  {
    "path": "src/toApiExternalType.js",
    "content": "import { toAsyncTypes } from './utils';\n\nexport default function toApiExternalType(actionType) {\n  const asyncTypes = toAsyncTypes(actionType);\n  return {\n    REQUEST: asyncTypes[0],\n    RESPONSE: asyncTypes[1],\n  };\n}\n"
  },
  {
    "path": "src/toExternalTypes.js",
    "content": "import { parseToUppercase } from './utils';\nimport toApiExternalType from './toApiExternalType';\n\nfunction getParser(singleConfig) {\n  return !singleConfig || !singleConfig.url\n    ? actionType => actionType\n    : toApiExternalType;\n}\n\nexport default function toExternalType(config, actionTypes) {\n  return Object.keys(actionTypes).reduce((acc, key) => {\n    const parse = getParser(config[key])\n\n    return {\n      ...acc,\n      [parseToUppercase(key)]: parse(actionTypes[key])\n    }\n  }, {});\n}\n"
  },
  {
    "path": "src/utils.js",
    "content": "export const isString = str => typeof str === 'string';\nexport const checkAction = type => type.length === 2 && type.every(isString);\nexport const parseToUppercase = (str) => str.replace(/([A-Z])/g, '_$1').toUpperCase();\n\nexport const removeNamespace = (str, NAMESPACE) => str.replace(`${NAMESPACE}_`, '');\n\nexport const toAsyncTypes = (type) => [`${type}_REQUEST`, `${type}_RESPONSE`];\n"
  },
  {
    "path": "src/validateConfig.js",
    "content": "import { parseToUppercase } from './utils';\n\nexport default function validateConfig(namespace, configs) {\n  Object.keys(configs).forEach((creatorName) => {\n    const config = configs[creatorName] || {};\n    const configName = `${namespace}_${parseToUppercase(creatorName)}`;\n\n    if (config.url && typeof config.url !== 'string' && typeof config.url !== 'function') {\n      throw new Error(\n        `Invalid url, ${config.url}, provided for ${configName}, it should be a string or a function that returns a string`,\n      );\n    }\n\n    if (config.url && (typeof config.method !== 'string' || !config.method.length)) {\n      throw new Error(\n        `Invalid method,  ${config.method}, provided for ${configName}, it should be a string`,\n      );\n    }\n    if (config.modifier && typeof config.modifier !== 'function') {\n      throw new Error(\n        `Invalid modifier handler, ${config.modifier}, provided for ${configName}, it should be a function`,\n      );\n    }\n  });\n\n  if (!namespace || typeof namespace !== 'string') {\n    throw new Error(`Invalid namespace provided: ${namespace}, it should be a string`);\n  }\n}\n"
  },
  {
    "path": "test/.eslintrc",
    "content": "{\n  \"env\": {\n    \"jest\": true\n  }\n}\n"
  },
  {
    "path": "test/constants.js",
    "content": "const urlFunction = (params) => `/${params.test}/`;\n\nexport const BASE_TYPES = {\n  list: 'MY_LIST',\n  listWithUrlFunction: 'MY_LIST_WITH_URL_FUNCTION',\n  read: 'MY_READ',\n  readWithExtras: 'MY_READ_WITH_EXTRAS',\n};\n\nexport const BASE_CONFIGS = {\n  list: { url: 'endpoint', method: 'get' },\n  listWithUrlFunction: { url: urlFunction, method: 'get' },\n  read: { url: 'endpoint/:id', method: 'put' },\n  readWithExtras: {\n    url: 'endpoint/:id',\n    method: 'put',\n    middlewares: ['myMiddleware'],\n  },\n};\n"
  },
  {
    "path": "test/createActions.spec.js",
    "content": "import createActions from '../src/createActions';\n\nconst baseConfigs = {\n  list: { url: 'endpoint', method: 'get' },\n  read: { url: 'endpoint/:id', method: 'put' },\n  readWithExtras: {\n    url: 'endpoint/:id',\n    method: 'put',\n    middlewares: ['middleware'],\n    meta: {\n      extraParam: 'EXTRA_PARAM',\n    }\n  },\n  reset: null,\n  clear: 1,\n  withDefaults: { payload: '1', meta: { foo: 'bar' }, error: true },\n  resetWithMeta: {\n    meta: {\n      a: 'TEST',\n      b: 'META_DATA',\n    },\n    payload: 'TEST_PAYLOAD',\n  }\n};\n\ndescribe('createActions', () => {\n  const { types, creators } = createActions('my', baseConfigs);\n\n  it('should return the proper types object', () => {\n    const expectedTypes = {\n      LIST: {\n        REQUEST: 'MY_LIST_REQUEST',\n        RESPONSE: 'MY_LIST_RESPONSE',\n      },\n      READ: {\n        REQUEST: 'MY_READ_REQUEST',\n        RESPONSE: 'MY_READ_RESPONSE',\n      },\n      READ_WITH_EXTRAS: {\n        REQUEST: 'MY_READ_WITH_EXTRAS_REQUEST',\n        RESPONSE: 'MY_READ_WITH_EXTRAS_RESPONSE',\n      },\n      RESET: 'MY_RESET',\n      WITH_DEFAULTS: 'MY_WITH_DEFAULTS',\n      CLEAR: 'MY_CLEAR',\n      RESET_WITH_META: 'MY_RESET_WITH_META',\n    };\n\n    expect(types).toEqual(expectedTypes);\n  });\n\n  it('should return the proper action when calling a creator without any value', () => {\n    expect(creators.list()).toEqual({\n      type: [types.LIST.REQUEST, types.LIST.RESPONSE],\n      meta: {\n        url: 'endpoint',\n        method: 'get',\n      },\n    });\n\n    expect(creators.reset()).toEqual({\n      type: types.RESET,\n    });\n  });\n\n  it('should parse the url with provided params', () => {\n    expect(creators.read(null, { id: '123' })).toEqual({\n      type: [types.READ.REQUEST, types.READ.RESPONSE],\n      meta: {\n        url: 'endpoint/123',\n        method: 'put',\n        id: '123',\n      },\n      payload: null,\n    });\n\n  });\n\n  it('should return the final action with given payload, meta and error', () => {\n    expect(creators.reset(null, { id: '123' }, false)).toEqual({\n      type: types.RESET,\n      meta: {\n        id: '123',\n      },\n      payload: null,\n      error: false,\n    });\n  });\n\n  it('should return the action with defaults values if configured', () => {\n    expect(creators.withDefaults()).toEqual({\n      type: types.WITH_DEFAULTS,\n      meta: {\n        foo: 'bar',\n      },\n      payload: '1',\n      error: true,\n    });\n  });\n\n  it('should return middlewares and any extra param inside meta', () => {\n    expect(creators.readWithExtras({ test: 'TEST' }, { id: '123' })).toEqual({\n      type: [types.READ_WITH_EXTRAS.REQUEST, types.READ_WITH_EXTRAS.RESPONSE],\n      payload: { test: 'TEST' },\n      meta: {\n        url: 'endpoint/123',\n        method: 'put',\n        id: '123',\n        middlewares: ['middleware'],\n        extraParam: 'EXTRA_PARAM',\n      },\n    });\n  });\n\n  it('should prefer the meta provided in the call ranther than the one from config', () => {\n    expect(creators.readWithExtras({ test: 'TEST' }, { id: '123', middlewares: ['override'] })).toEqual({\n      type: [types.READ_WITH_EXTRAS.REQUEST, types.READ_WITH_EXTRAS.RESPONSE],\n      payload: { test: 'TEST' },\n      meta: {\n        url: 'endpoint/123',\n        method: 'put',\n        id: '123',\n        middlewares: ['override'],\n        extraParam: 'EXTRA_PARAM',\n      },\n    });\n  })\n});\n"
  },
  {
    "path": "test/createAsyncMiddleware.spec.js",
    "content": "/* eslint-disable import/first */\njest.mock('../src/requestMiddlewares', () => ({\n  globalMiddlewares: {},\n  onCallApply: jest.fn((applyPoint) => store => done =>\n  (action, error, response) => done(action, error, response))\n}));\nconst middlewares = require('../src/requestMiddlewares');\n\nconst get = policeNames => middlewares.onCallApply;\nmiddlewares.getRequestMiddlewares = jest.fn((middlewares) => {\n  if (Array.isArray(middlewares)) {\n    return get(middlewares);\n  }\n  return get([]);\n});\n\n\n// eslint-disable-next-line import/first\nimport createAsyncMiddleware from '../src/createAsyncMiddleware';\nimport middlewaresMock from '../src/requestMiddlewares';\n\nconst storeApi = {\n  dispatch: jest.fn(() => {}),\n  getState: jest.fn(() => {}),\n};\n\nconst API_RESPONSE = 'API_RESPONSE';\nconst API_ERROR = 'API_ERROR';\n\nconst asyncTask = store => done => (action) => {\n  done(null, API_RESPONSE);\n  return API_RESPONSE;\n};\n\nconst asyncErrorTask = store => done => (action) => {\n  done(API_ERROR, null);\n  return API_ERROR;\n};\n\ndescribe('createAsyncMiddleware', () => {\n  it('should throw if you does not provide an asyncTask function', () => {\n    expect(() => createAsyncMiddleware()).toThrow()\n    expect(() => createAsyncMiddleware('test')).toThrow();\n  });\n\n  it('should not intercept regular actions', () => {\n    const nextMock = jest.fn();\n    const apiMiddleware = createAsyncMiddleware(asyncTask)(storeApi)(nextMock);\n\n    apiMiddleware({ type: 'REGULAR_ACTION', meta: {}, });\n    expect(nextMock.mock.calls.length).toBe(1);\n  });\n\n  it('should throw for invalid types', () => {\n    const nextMock = jest.fn();\n    const apiMiddleware = createAsyncMiddleware(asyncTask)(storeApi)(nextMock);\n\n    expect(() => apiMiddleware({ type: ['REGULAR_ACTION', 2], meta: {} })).toThrow();\n  });\n\n  it('should throw when has no meta in the action', () => {\n    const nextMock = jest.fn();\n    const apiMiddleware = createAsyncMiddleware(asyncTask)(storeApi)(nextMock);\n\n    expect(() => apiMiddleware({ type: ['REGULAR_ACTION', '2'] })).toThrow();\n  });\n\n  it('should get actionPolicies passing the proper argument', () => {\n    const nextMock = jest.fn();\n    const apiMiddleware = createAsyncMiddleware(asyncTask)(storeApi)(nextMock);\n    const middlewares = ['mypolice'];\n    apiMiddleware({\n      type: ['REQUEST_ACTION', 'RESPONSE_ACTION'],\n      meta: {\n        middlewares,\n      },\n    });\n    expect(middlewaresMock.getRequestMiddlewares.mock.calls.length).toBe(1);\n    expect(middlewaresMock.getRequestMiddlewares.mock.calls[0][0]).toBe(middlewares);\n    middlewaresMock.getRequestMiddlewares.mockClear();\n    middlewaresMock.onCallApply.mockClear();\n    storeApi.dispatch.mockClear();\n  });\n\n  it('should execute the middlewares in the sequence', () => {\n    const nextMock = jest.fn();\n    const apiMiddleware = createAsyncMiddleware(asyncTask)(storeApi)(nextMock);\n    const middlewares = ['mypolice'];\n    const returnValue = apiMiddleware({\n      type: ['REQUEST_ACTION', 'RESPONSE_ACTION'],\n      meta: {\n        middlewares,\n      },\n    });\n\n    expect(returnValue).toBe(API_RESPONSE);\n    expect(middlewaresMock.onCallApply.mock.calls.length).toBe(2);\n    expect(middlewaresMock.onCallApply.mock.calls[0][0]).toBe('onRequest');\n    expect(middlewaresMock.onCallApply.mock.calls[1][0]).toBe('onResponse');\n    storeApi.dispatch.mockClear();\n  });\n\n  it('should dispatch an action with error when get error from the asyncTask', () => {\n    const nextMock = jest.fn();\n    const apiMiddleware = createAsyncMiddleware(asyncErrorTask)(storeApi)(nextMock);\n    const middlewares = ['mypolice'];\n    const returnValue = apiMiddleware({\n      type: ['REQUEST_ACTION', 'RESPONSE_ACTION'],\n      meta: {\n        middlewares,\n      },\n    });\n\n    expect(returnValue).toBe(API_ERROR);\n    expect(storeApi.dispatch.mock.calls.length).toBe(2);\n    expect(storeApi.dispatch.mock.calls[0][0].type).toBe('REQUEST_ACTION');\n    expect(storeApi.dispatch.mock.calls[1][0].type).toBe('RESPONSE_ACTION');\n    expect(storeApi.dispatch.mock.calls[1][0].error).toBe(true);\n    expect(storeApi.dispatch.mock.calls[1][0].payload).toBe(API_ERROR);\n  });\n\n  it('should call asyncTask with the store', () => {\n    const asyncTaskMock = jest.fn();\n    asyncTaskMock.mockReturnValue(() => () => {});\n    const apiMiddleware = createAsyncMiddleware(asyncTaskMock)(storeApi)(() => {});\n    apiMiddleware({\n      type: ['REQUEST_ACTION', 'RESPONSE_ACTION'],\n      meta: {},\n    });\n\n    expect(asyncTaskMock.mock.calls[0][0]).toBe(storeApi);\n    storeApi.dispatch.mockClear();\n  })\n});\n"
  },
  {
    "path": "test/createCreators.spec.js",
    "content": "import createCreators from '../src/createCreators';\nimport apiActionCreatorFactory from '../src/apiActionCreatorFactory';\n\nconst urlFunction = (params) => `/${params.test}/`;\n\nconst BASE_TYPES = {\n  list: 'MY_LIST',\n  listWithUrlFunction: 'MY_LIST_WITH_URL_FUNCTION',\n  read: 'MY_READ',\n  readWithExtras: 'MY_READ_WITH_EXTRAS',\n};\n\nconst BASE_CONFIGS = {\n  list: { url: 'endpoint', method: 'get' },\n  listWithUrlFunction: { url: urlFunction, method: 'get' },\n  read: { url: 'endpoint/:id', method: 'put' },\n  readWithExtras: {\n    url: 'endpoint/:id',\n    method: 'put',\n    middlewares: ['myMiddleware'],\n  },\n};\n\n\ndescribe('createCreators', () => {\n  it('should return an action creator', () => {\n    const creators = createCreators(BASE_CONFIGS, BASE_TYPES, apiActionCreatorFactory);\n\n    expect(creators.list()).toEqual({\n      type: ['MY_LIST_REQUEST', 'MY_LIST_RESPONSE'],\n      meta: {\n        url: 'endpoint',\n        method: 'get',\n      },\n      payload: undefined,\n    });\n\n    expect(creators.listWithUrlFunction(null, { test: 1232 })).toEqual({\n      type: [\n        'MY_LIST_WITH_URL_FUNCTION_REQUEST',\n        'MY_LIST_WITH_URL_FUNCTION_RESPONSE'\n      ],\n      meta: {\n        url: urlFunction({ test: 1232 }),\n        method: 'get',\n        test: 1232,\n      },\n      payload: null,\n    });\n\n    expect(creators.read(null, { id: '123' })).toEqual({\n      type: ['MY_READ_REQUEST', 'MY_READ_RESPONSE'],\n      meta: {\n        url: 'endpoint/123',\n        method: 'put',\n        id: '123',\n      },\n      payload: null\n    });\n\n    expect(creators.readWithExtras(null, { id: '123' })).toEqual({\n      type: ['MY_READ_WITH_EXTRAS_REQUEST', 'MY_READ_WITH_EXTRAS_RESPONSE'],\n      meta: {\n        url: 'endpoint/123',\n        method: 'put',\n        id: '123',\n        middlewares: ['myMiddleware'],\n      },\n      payload: null,\n    });\n  });\n});\n"
  },
  {
    "path": "test/createReducers.spec.js",
    "content": "import createReducers from '../src/createReducers';\n\nconst expectedToThrow = `All keys must be valid types and all values should be functions:\n{\n  a: 👉 'test',\n  👉 undefined: function Test(state, action) { ... },\n  b: function b() { ... },\n  c: function c() { ... },\n  d: 👉 null,\n  👉 [object Object]: 👉 null,\n  e: 👉 1,\n  f: 👉 undefined,\n}`;\n\ndescribe('createReducers', () => {\n  const INCLUDE_C = 'INCLUDE_C';\n  const INCLUDE_D = 'INCLUDE_D';\n  const ACTION_NOT_REGISTERED = 'ACTION_NOT_REGISTERED';\n  const INITIAL_STATE = {\n    a: 'A',\n    b: 'B',\n  };\n\n  const HANDLERS = {\n    [INCLUDE_C]: (state = INITIAL_STATE, action) => ({\n      ...state,\n      c: 'C',\n    }),\n    [INCLUDE_D]: (state = INITIAL_STATE, action) => ({\n      ...state,\n      d: 'D',\n    }),\n  };\n\n  it('should throw when a key is not defined', () => {\n    expect(() => {\n      const key = undefined;\n      createReducers({}, {\n        [key]: function() {},\n      })\n    }).toThrow();\n  });\n\n  it('should throw when a key is invalid', () => {\n    expect(() => {\n      const key = { foo: 'bar' };\n      createReducers({}, {\n        [key]: function() {},\n      })\n    }).toThrow();\n  });\n\n  it('should throw when a reducer is not a function', () => {\n    expect(() => {\n      createReducers({}, { a: '' });\n    }).toThrow();\n  });\n\n  it('should throw if handlers is empty', () => {\n    expect(() => {\n      createReducers({}, null);\n    }).toThrow('Invalid handler: null');\n  });\n\n  it('should proper format the error message', () => {\n    expect(() => {\n      const key = undefined;\n      createReducers({}, {\n        a: 'test',\n        [key]: function Test(state, action) {\n          return {\n            ...state,\n            foo: 'bar',\n          }\n        },\n        b: () => {},\n        c: function() {},\n        d: null,\n        [{}]: null,\n        e: 1,\n        f: undefined,\n      })\n    }).toThrow(expectedToThrow);\n  });\n\n  const reducer = createReducers(INITIAL_STATE, HANDLERS);\n\n  it('should return same state when no reducers found for the action', () => {\n    expect(reducer(INITIAL_STATE, { type: ACTION_NOT_REGISTERED })).toEqual(INITIAL_STATE);\n  })\n\n  it('should provide the correct state', () => {\n    expect(reducer({ z: 'z', y: 'y'}, { type: ACTION_NOT_REGISTERED })).toEqual({ z: 'z', y: 'y'});\n  });\n\n  it('should return the current state if there is no action', () => {\n    expect(reducer({ z: 'z', y: 'y'})).toEqual({ z: 'z', y: 'y'});\n  });\n\n  it('should return assume INITIAL_STATE when no state is provided', () => {\n    expect(reducer()).toEqual(INITIAL_STATE);\n  });\n\n  it('should call only the reducer registered for the action', () => {\n    expect(reducer(INITIAL_STATE, { type: INCLUDE_C })).toEqual({\n      a: 'A',\n      b: 'B',\n      c: 'C',\n    });\n\n    expect(reducer(INITIAL_STATE, { type: INCLUDE_D })).toEqual({\n      a: 'A',\n      b: 'B',\n      d: 'D',\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/createTypes.spec.js",
    "content": "import createTypes from '../src/createTypes';\n\ndescribe('createTypes', () => {\n  it('should return an object with the respective action types', () => {\n    const actionTypes = createTypes(['list', 'softDelete'], 'MY');\n\n    expect(actionTypes).toEqual({\n      list: 'MY_LIST',\n      softDelete: 'MY_SOFT_DELETE',\n    });\n  });\n});\n"
  },
  {
    "path": "test/middlewareWithRedux.spec.js",
    "content": "import { createStore, applyMiddleware } from 'redux';\nimport createAsyncMiddleware from '../src/createAsyncMiddleware';\n\n\ndescribe('Testing middleware on redux', () => {\n  const SINGULAR_RESPONSE = 'SINGULAR_RESPONSE';\n  const asyncTask = store => next => (action) => {\n    next(null, SINGULAR_RESPONSE);\n\n    const promise = new Promise((resolve, reject) => {\n      resolve(SINGULAR_RESPONSE);\n    });\n\n    return promise;\n  };\n\n  const mockReducer = jest.fn((state, action) => state);\n  const createStoreWithHamal = applyMiddleware(createAsyncMiddleware(asyncTask))(createStore);\n  const store = createStoreWithHamal(mockReducer);\n\n  it('should dispatch the actions', (done) => {\n    mockReducer.mockClear();\n    const returnedValue = store.dispatch({\n      type: ['REQUEST_ACTION', 'RESPONSE_ACTION'],\n      meta: { url: 'test' },\n      payload: {},\n    });\n\n    expect(mockReducer.mock.calls[0][1]).toEqual({\n      type: 'REQUEST_ACTION',\n      meta: { url: 'test' },\n      payload: {},\n    });\n\n    expect(mockReducer.mock.calls[1][1]).toEqual({\n      type: 'RESPONSE_ACTION',\n      meta: { url: 'test' },\n      payload: SINGULAR_RESPONSE,\n    });\n\n    returnedValue.then((value) => {\n      done();\n      expect(value).toBe(SINGULAR_RESPONSE);\n    })\n  });\n\n  it('should perform middlewares over the actions', (done) => {\n    mockReducer.mockClear();\n\n    const onRequestMiddleware = store => done => (action, error, response) =>\n      done({\n        ...action,\n        meta: { ...action.meta, onRequest: true },\n      }, error, response);\n\n    onRequestMiddleware.applyPoint = 'onRequest';\n\n    const onResponseMiddleware = store => done => (action, error, response) =>\n      done({\n        ...action,\n        meta: { ...action.meta, onResponse: true },\n      }, error, response);\n\n    onResponseMiddleware.applyPoint = 'onResponse';\n\n    const returnedValue = store.dispatch({\n      type: ['REQUEST_ACTION', 'RESPONSE_ACTION'],\n      payload: {},\n      meta: {\n        url: 'test',\n        middlewares: [onRequestMiddleware, onResponseMiddleware],\n        extras: true\n      },\n    });\n\n    expect(mockReducer.mock.calls[0][1]).toEqual({\n      type: 'REQUEST_ACTION',\n      payload: {},\n      meta: {\n        url: 'test',\n        middlewares: [onRequestMiddleware, onResponseMiddleware],\n        extras: true,\n        onRequest: true,\n      },\n    });\n\n    expect(mockReducer.mock.calls[1][1]).toEqual({\n      type: 'RESPONSE_ACTION',\n      meta: {\n        url: 'test',\n        middlewares: [onRequestMiddleware, onResponseMiddleware],\n        extras: true, onResponse: true, onRequest: true,\n      }, // Passed through both middlewares\n      payload: SINGULAR_RESPONSE,\n    });\n\n    returnedValue.then((value) => {\n      done();\n      expect(value).toBe(SINGULAR_RESPONSE);\n    });\n  });\n});\n"
  },
  {
    "path": "test/parseUrl.spec.js",
    "content": "import parseUrl from '../src/parseUrl';\n\n\ndescribe('parseUrl', () => {\n  it('should ignore url without params', () => {\n    expect(parseUrl('regular/endpoint')).toBe('regular/endpoint');\n  });\n\n  it('should throw if param isnt present', () => {\n    expect(() => parseUrl('endpoint/:myparam', {})).toThrow(\n      'Param myparam from url endpoint/:myparam, not found in params object'\n    );\n  });\n\n  it('should parse params', () => {\n    expect(parseUrl('endpoint/:myparam', { myparam: 'hey-ho'})).toBe('endpoint/hey-ho');\n  });\n\n  it('should ignore the begning of a absolute url', () => {\n    expect(() => parseUrl('https://ds.devel.goben.rocks/api:8080', {})).not.toThrow();\n\n    expect(parseUrl('https://ds.devel.goben.rocks/api:8080', {}))\n      .toBe('https://ds.devel.goben.rocks/api:8080');\n  });\n});\n"
  },
  {
    "path": "test/publicApi.spec.js",
    "content": "import {\n  createActions,\n  createAsyncMiddleware,\n  createReducers,\n  middlewares,\n} from '../src';\n\nconst publicNames = [\n  'createActions',\n  'createAsyncMiddleware',\n  'createReducers',\n  'middlewares',\n];\n\ndescribe('publicApi', () => {\n  [\n    createActions,\n    createAsyncMiddleware,\n    createReducers,\n    middlewares,\n  ].map((value, index) => {\n    it(`should ${publicNames[index]} be present`, () => {\n      expect(!!value).toBe(true);\n    });\n  });\n});\n"
  },
  {
    "path": "test/requestMiddlewares.spec.js",
    "content": "import { getRequestMiddlewares } from '../src/requestMiddlewares';\n\ndescribe('getRequestMiddlewares', () => {\n  const SINGULAR_VALUE = 'SINGULAR_VALUE';\n  test('should get the police runner for the given police array', (done) => {\n    const myMiddleware = store => next => (action, error, response) => {\n      return next({ ...action, myMiddlewareWasHere: true }, error, response);\n    };\n    myMiddleware.applyPoint = 'onRequest';\n\n    const myAction = { type: 'REQUEST' };\n    const reqMiddlewares = getRequestMiddlewares([myMiddleware]);\n    const callback = (action) => {\n      expect(action.myMiddlewareWasHere).toBe(true);\n\n      done();\n      return SINGULAR_VALUE;\n    };\n    const result = reqMiddlewares('onRequest')({})(callback)(myAction, null, null);\n    expect(result).toBe(SINGULAR_VALUE);\n  });\n\n  test('should run even without middlewares registered', (done) => {\n    const myAction = { type: 'REQUEST' }\n    const reqMiddlewares = getRequestMiddlewares(undefined);\n    const callback = (action) => {\n      expect(action).toBe(myAction);\n      done();\n      return SINGULAR_VALUE;\n    };\n    const result = reqMiddlewares('onRequest')({})(callback)(myAction, null, null);\n    expect(result).toBe(SINGULAR_VALUE);\n  });\n\n  test('Should throw when trying to use a invalid middleware', () => {\n    const invalidMiddleware = {};\n\n    expect(\n      () => getRequestMiddlewares(['invalidMiddlewareString', invalidMiddleware])\n    ).toThrowError(\n      `All middlewares should be functions: [invalidMiddlewareString,[object Object]]`\n    );\n  });\n\n  test('Should run the middlewares in the given order', (done) => {\n    const appendB = store => next => (action, error, response) =>\n      next({ ...action, payload: action.payload + 'B' }, error, response);\n\n    appendB.applyPoint = 'onRequest';\n\n    const appendC = store => next => (action, error, response) =>\n      next({ ...action, payload: action.payload + 'C' }, error, response);\n    appendC.applyPoint = 'onRequest';\n\n    const appendD = store => next => (action, error, response) =>\n      next({ ...action, payload: action.payload + 'D' }, error, response);\n\n    appendD.applyPoint = 'onRequest';\n\n    const myAction = { type: 'REQUEST', payload: 'A' };\n    const runner = getRequestMiddlewares([appendB, appendC, appendD]);\n    const callback = (action) => {\n      expect(action.payload).toBe('ABCD');\n\n      done();\n      return action.payload;\n    };\n    const result = runner('onRequest')({})(callback)(myAction, null, null);\n    expect(result).toBe('ABCD');\n  })\n});\n\n\n\n\n\n\n"
  },
  {
    "path": "test/toExternalTypes.spec.js",
    "content": "import toExternalTypes from '../src/toExternalTypes';\n\nconst baseConfig = {\n  list: { url: 'test' },\n  listWithUrlFunction: { url: 'test' },\n  read: { url: 'test' },\n  readWithExtras: { url: 'test' },\n  fsaAction: null,\n  secondFsaAction: {},\n}\n\ndescribe('toExternalTypes', () => {\n  const reducedTypes = toExternalTypes(baseConfig, {\n    list: 'MY_LIST',\n    listWithUrlFunction: 'MY_LIST_WITH_URL_FUNCTION',\n    read: 'MY_READ',\n    readWithExtras: 'MY_READ_WITH_EXTRAS',\n    fsaAction: 'MY_FSA_ACTION',\n    secondFsaAction: 'MY_SECOND_FSA_ACTION',\n  });\n\n  it('should return the types formatted in async types, to be used by reducers', () => {\n    expect(reducedTypes).toEqual({\n      LIST: {\n        REQUEST: 'MY_LIST_REQUEST',\n        RESPONSE: 'MY_LIST_RESPONSE',\n      },\n      LIST_WITH_URL_FUNCTION: {\n        REQUEST: 'MY_LIST_WITH_URL_FUNCTION_REQUEST',\n        RESPONSE: 'MY_LIST_WITH_URL_FUNCTION_RESPONSE',\n      },\n      READ: {\n        REQUEST: 'MY_READ_REQUEST',\n        RESPONSE: 'MY_READ_RESPONSE',\n      },\n      READ_WITH_EXTRAS: {\n        REQUEST: 'MY_READ_WITH_EXTRAS_REQUEST',\n        RESPONSE: 'MY_READ_WITH_EXTRAS_RESPONSE',\n      },\n      FSA_ACTION: 'MY_FSA_ACTION',\n      SECOND_FSA_ACTION: 'MY_SECOND_FSA_ACTION',\n    });\n  })\n});\n"
  },
  {
    "path": "test/validateConfig.spec.js",
    "content": "import validateConfig from '../src/validateConfig';\n\ndescribe('validateConfig', () => {\n  it('throws when provide a wrong url', () => {\n    expect(() => validateConfig('my', { list: { url: 1 } })).toThrow();\n  });\n\n  it('throws when not provide a method', () => {\n    expect(() => validateConfig('my', { list: { url: 'path/:id' } })).toThrow();\n  });\n\n  it('throws when modifier is not a function', () => {\n    expect(() =>\n      validateConfig('my', { list: { url: 'path/:id', method: 'save', modifier: {} } })\n    ).toThrow();\n  });\n\n  it('throws when namespace is not a string', () => {\n    expect(() =>\n      validateConfig(1, {\n        list: { url: 'path/:id', method: 'save', modifier: '' }\n      })\n    ).toThrow();\n  });\n\n  it('should not throw when provide a valid config', () => {\n    expect(() =>\n      validateConfig('my', { list: { url: 'path/:id', method: 'save', modifier: () => {} } })\n    ).not.toThrow();\n  });\n});\n"
  }
]