[
  {
    "path": ".idea/.name",
    "content": "expresshapinnes-official"
  },
  {
    "path": ".idea/encodings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"Encoding\" useUTFGuessing=\"true\" native2AsciiForPropertiesFiles=\"false\" />\n</project>"
  },
  {
    "path": ".idea/expresshapinnes-official.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"WEB_MODULE\" version=\"4\">\n  <component name=\"NewModuleRootManager\">\n    <content url=\"file://$MODULE_DIR$\" />\n    <orderEntry type=\"inheritedJdk\" />\n    <orderEntry type=\"sourceFolder\" forTests=\"false\" />\n  </component>\n</module>"
  },
  {
    "path": ".idea/misc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectRootManager\" version=\"2\" />\n</project>"
  },
  {
    "path": ".idea/modules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n      <module fileurl=\"file://$PROJECT_DIR$/.idea/expresshapinnes-official.iml\" filepath=\"$PROJECT_DIR$/.idea/expresshapinnes-official.iml\" />\n    </modules>\n  </component>\n</project>"
  },
  {
    "path": ".idea/scopes/scope_settings.xml",
    "content": "<component name=\"DependencyValidationManager\">\n  <state>\n    <option name=\"SKIP_IMPORT_STATEMENTS\" value=\"false\" />\n  </state>\n</component>"
  },
  {
    "path": ".idea/vcs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping directory=\"\" vcs=\"\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/workspace.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ChangeListManager\">\n    <list default=\"true\" id=\"d9269681-97c6-4fc2-9aef-be25035f51df\" name=\"Default\" comment=\"\" />\n    <ignored path=\"expresshapinnes-official.iws\" />\n    <ignored path=\".idea/workspace.xml\" />\n    <option name=\"EXCLUDED_CONVERTED_TO_IGNORED\" value=\"true\" />\n    <option name=\"TRACKING_ENABLED\" value=\"true\" />\n    <option name=\"SHOW_DIALOG\" value=\"false\" />\n    <option name=\"HIGHLIGHT_CONFLICTS\" value=\"true\" />\n    <option name=\"HIGHLIGHT_NON_ACTIVE_CHANGELIST\" value=\"false\" />\n    <option name=\"LAST_RESOLUTION\" value=\"IGNORE\" />\n  </component>\n  <component name=\"ChangesViewManager\" flattened_view=\"true\" show_ignored=\"false\" />\n  <component name=\"CreatePatchCommitExecutor\">\n    <option name=\"PATCH_PATH\" value=\"\" />\n  </component>\n  <component name=\"DaemonCodeAnalyzer\">\n    <disable_hints />\n  </component>\n  <component name=\"ExecutionTargetManager\" SELECTED_TARGET=\"default_target\" />\n  <component name=\"FavoritesManager\">\n    <favorites_list name=\"expresshapinnes-official\" />\n  </component>\n  <component name=\"FileEditorManager\">\n    <leaf>\n      <file leaf-file-name=\"server.js\" pinned=\"false\" current-in-tab=\"false\">\n        <entry file=\"file://$PROJECT_DIR$/test/server.js\">\n          <provider selected=\"true\" editor-type-id=\"text-editor\">\n            <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"795\">\n              <caret line=\"37\" column=\"15\" selection-start-line=\"37\" selection-start-column=\"15\" selection-end-line=\"37\" selection-end-column=\"15\" />\n              <folding />\n            </state>\n          </provider>\n        </entry>\n      </file>\n      <file leaf-file-name=\"reusableFields.js\" pinned=\"false\" current-in-tab=\"false\">\n        <entry file=\"file://$PROJECT_DIR$/test/reusableFields.js\">\n          <provider selected=\"true\" editor-type-id=\"text-editor\">\n            <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"540\" max-vertical-offset=\"3585\">\n              <caret line=\"33\" column=\"30\" selection-start-line=\"33\" selection-start-column=\"16\" selection-end-line=\"33\" selection-end-column=\"30\" />\n              <folding>\n                <element signature=\"n#!!doc\" expanded=\"true\" />\n              </folding>\n            </state>\n          </provider>\n        </entry>\n      </file>\n      <file leaf-file-name=\"RESTcallsValidator.js\" pinned=\"false\" current-in-tab=\"false\">\n        <entry file=\"file://$PROJECT_DIR$/test/node_modules/express-happiness/RESTcallsValidator.js\">\n          <provider selected=\"true\" editor-type-id=\"text-editor\">\n            <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"2823\" max-vertical-offset=\"4020\">\n              <caret line=\"47\" column=\"0\" selection-start-line=\"47\" selection-start-column=\"0\" selection-end-line=\"47\" selection-end-column=\"0\" />\n              <folding />\n            </state>\n          </provider>\n        </entry>\n      </file>\n      <file leaf-file-name=\"layer.js\" pinned=\"false\" current-in-tab=\"false\">\n        <entry file=\"file://$PROJECT_DIR$/test/node_modules/express/lib/router/layer.js\">\n          <provider selected=\"true\" editor-type-id=\"text-editor\">\n            <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"846\" max-vertical-offset=\"2580\">\n              <caret line=\"83\" column=\"0\" selection-start-line=\"83\" selection-start-column=\"0\" selection-end-line=\"83\" selection-end-column=\"0\" />\n              <folding />\n            </state>\n          </provider>\n        </entry>\n      </file>\n      <file leaf-file-name=\"route.js\" pinned=\"false\" current-in-tab=\"false\">\n        <entry file=\"file://$PROJECT_DIR$/test/node_modules/express/lib/router/route.js\">\n          <provider selected=\"true\" editor-type-id=\"text-editor\">\n            <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"996\" max-vertical-offset=\"2835\">\n              <caret line=\"93\" column=\"0\" selection-start-line=\"93\" selection-start-column=\"0\" selection-end-line=\"93\" selection-end-column=\"0\" />\n              <folding />\n            </state>\n          </provider>\n        </entry>\n      </file>\n      <file leaf-file-name=\"expressHappiness.js\" pinned=\"false\" current-in-tab=\"false\">\n        <entry file=\"file://$PROJECT_DIR$/test/node_modules/express-happiness/expressHappiness.js\">\n          <provider selected=\"true\" editor-type-id=\"text-editor\">\n            <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"6813\" max-vertical-offset=\"8010\">\n              <caret line=\"449\" column=\"15\" selection-start-line=\"449\" selection-start-column=\"8\" selection-end-line=\"449\" selection-end-column=\"15\" />\n              <folding />\n            </state>\n          </provider>\n        </entry>\n      </file>\n      <file leaf-file-name=\"ErrorHandler.js\" pinned=\"false\" current-in-tab=\"false\">\n        <entry file=\"file://$PROJECT_DIR$/test/node_modules/express-happiness/ErrorHandler.js\">\n          <provider selected=\"true\" editor-type-id=\"text-editor\">\n            <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"675\">\n              <caret line=\"20\" column=\"0\" selection-start-line=\"0\" selection-start-column=\"0\" selection-end-line=\"39\" selection-end-column=\"30\" />\n              <folding />\n            </state>\n          </provider>\n        </entry>\n      </file>\n      <file leaf-file-name=\"helpers.js\" pinned=\"false\" current-in-tab=\"false\">\n        <entry file=\"file://$PROJECT_DIR$/helpers/helpers.js\">\n          <provider selected=\"true\" editor-type-id=\"text-editor\">\n            <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"1035\">\n              <caret line=\"0\" column=\"0\" selection-start-line=\"0\" selection-start-column=\"0\" selection-end-line=\"0\" selection-end-column=\"0\" />\n              <folding />\n            </state>\n          </provider>\n        </entry>\n      </file>\n      <file leaf-file-name=\"ErrorHandler.js\" pinned=\"false\" current-in-tab=\"true\">\n        <entry file=\"file://$PROJECT_DIR$/ErrorHandler.js\">\n          <provider selected=\"true\" editor-type-id=\"text-editor\">\n            <state vertical-scroll-proportion=\"0.48872182\" vertical-offset=\"0\" max-vertical-offset=\"1197\">\n              <caret line=\"39\" column=\"30\" selection-start-line=\"39\" selection-start-column=\"30\" selection-end-line=\"39\" selection-end-column=\"30\" />\n              <folding />\n            </state>\n          </provider>\n        </entry>\n      </file>\n    </leaf>\n  </component>\n  <component name=\"IdeDocumentHistory\">\n    <option name=\"CHANGED_PATHS\">\n      <list>\n        <option value=\"$PROJECT_DIR$/test/package.json\" />\n        <option value=\"$PROJECT_DIR$/controllerFunctions.js\" />\n        <option value=\"$PROJECT_DIR$/package.json\" />\n        <option value=\"$PROJECT_DIR$/views/index.html\" />\n        <option value=\"$PROJECT_DIR$/test/mockdata/getTraffic.json\" />\n        <option value=\"$PROJECT_DIR$/test/conf/conf.js\" />\n        <option value=\"$PROJECT_DIR$/test/controllerFunctions.js\" />\n        <option value=\"$PROJECT_DIR$/expressHappiness.js\" />\n        <option value=\"$PROJECT_DIR$/test/conf/errors.js\" />\n        <option value=\"$PROJECT_DIR$/test/server.js\" />\n        <option value=\"$PROJECT_DIR$/test/conf/restConf.js\" />\n        <option value=\"$PROJECT_DIR$/test/reusableFields.js\" />\n        <option value=\"$PROJECT_DIR$/test/errors.log\" />\n        <option value=\"$PROJECT_DIR$/test/node_modules/express-happiness/RESTcallsValidator.js\" />\n        <option value=\"$PROJECT_DIR$/RESTcallsValidator.js\" />\n        <option value=\"$PROJECT_DIR$/test/node_modules/express-happiness/ErrorHandler.js\" />\n        <option value=\"$PROJECT_DIR$/ErrorHandler.js\" />\n      </list>\n    </option>\n  </component>\n  <component name=\"JsGulpfileManager\">\n    <detection-done>true</detection-done>\n  </component>\n  <component name=\"ProjectFrameBounds\">\n    <option name=\"x\" value=\"1920\" />\n    <option name=\"y\" value=\"-295\" />\n    <option name=\"width\" value=\"1200\" />\n    <option name=\"height\" value=\"1920\" />\n  </component>\n  <component name=\"ProjectLevelVcsManager\" settingsEditedManually=\"false\">\n    <OptionsSetting value=\"true\" id=\"Add\" />\n    <OptionsSetting value=\"true\" id=\"Remove\" />\n    <OptionsSetting value=\"true\" id=\"Checkout\" />\n    <OptionsSetting value=\"true\" id=\"Update\" />\n    <OptionsSetting value=\"true\" id=\"Status\" />\n    <OptionsSetting value=\"true\" id=\"Edit\" />\n    <ConfirmationsSetting value=\"0\" id=\"Add\" />\n    <ConfirmationsSetting value=\"0\" id=\"Remove\" />\n  </component>\n  <component name=\"ProjectView\">\n    <navigator currentView=\"ProjectPane\" proportions=\"\" version=\"1\">\n      <flattenPackages />\n      <showMembers />\n      <showModules />\n      <showLibraryContents />\n      <hideEmptyPackages />\n      <abbreviatePackageNames />\n      <autoscrollToSource />\n      <autoscrollFromSource />\n      <sortByType />\n    </navigator>\n    <panes>\n      <pane id=\"ProjectPane\">\n        <subPane>\n          <PATH>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"expresshapinnes-official\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode\" />\n            </PATH_ELEMENT>\n          </PATH>\n          <PATH>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"expresshapinnes-official\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"expresshapinnes-official\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n          </PATH>\n          <PATH>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"expresshapinnes-official\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"expresshapinnes-official\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"views\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n          </PATH>\n          <PATH>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"expresshapinnes-official\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"expresshapinnes-official\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"test\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n          </PATH>\n          <PATH>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"expresshapinnes-official\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"expresshapinnes-official\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"test\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"node_modules\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n          </PATH>\n          <PATH>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"expresshapinnes-official\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"expresshapinnes-official\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"test\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"node_modules\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"express-happiness\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n          </PATH>\n          <PATH>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"expresshapinnes-official\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"expresshapinnes-official\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"test\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"mockdata\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n          </PATH>\n          <PATH>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"expresshapinnes-official\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"expresshapinnes-official\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"test\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"conf\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n          </PATH>\n          <PATH>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"expresshapinnes-official\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"expresshapinnes-official\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"helpers\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n          </PATH>\n        </subPane>\n      </pane>\n      <pane id=\"Scope\" />\n    </panes>\n  </component>\n  <component name=\"PropertiesComponent\">\n    <property name=\"WebServerToolWindowFactoryState\" value=\"false\" />\n    <property name=\"last_opened_file_path\" value=\"$PROJECT_DIR$\" />\n    <property name=\"HbShouldOpenHtmlAsHb\" value=\"\" />\n    <property name=\"FullScreen\" value=\"false\" />\n    <property name=\"recentsLimit\" value=\"5\" />\n    <property name=\"restartRequiresConfirmation\" value=\"true\" />\n  </component>\n  <component name=\"RecentsManager\">\n    <key name=\"CopyFile.RECENT_KEYS\">\n      <recent name=\"$PROJECT_DIR$/test\" />\n      <recent name=\"$PROJECT_DIR$/test/conf\" />\n      <recent name=\"$PROJECT_DIR$/views\" />\n      <recent name=\"$PROJECT_DIR$\" />\n    </key>\n    <key name=\"MoveFile.RECENT_KEYS\">\n      <recent name=\"$PROJECT_DIR$/test\" />\n    </key>\n  </component>\n  <component name=\"RunManager\" selected=\"Node.js.server.js\">\n    <configuration default=\"false\" name=\"server.js\" type=\"NodeJSConfigurationType\" factoryName=\"Node.js\" temporary=\"true\" path-to-node=\"/usr/local/bin/node\" path-to-js-file=\"server.js\" working-dir=\"$PROJECT_DIR$/test\">\n      <RunnerSettings RunnerId=\"Basic\" />\n      <RunnerSettings RunnerId=\"debuggableProgram\" />\n      <ConfigurationWrapper RunnerId=\"Basic\" />\n      <ConfigurationWrapper RunnerId=\"debuggableProgram\" />\n      <method />\n    </configuration>\n    <configuration default=\"false\" name=\"RESTcallsValidator.js\" type=\"NodeJSConfigurationType\" factoryName=\"Node.js\" temporary=\"true\" path-to-node=\"/usr/local/bin/node\" path-to-js-file=\"RESTcallsValidator.js\" working-dir=\"$PROJECT_DIR$/test/node_modules/express-happiness\">\n      <RunnerSettings RunnerId=\"debuggableProgram\" />\n      <ConfigurationWrapper RunnerId=\"debuggableProgram\" />\n      <method />\n    </configuration>\n    <configuration default=\"false\" name=\"route.js\" type=\"NodeJSConfigurationType\" factoryName=\"Node.js\" temporary=\"true\" path-to-node=\"/usr/local/bin/node\" path-to-js-file=\"route.js\" working-dir=\"$PROJECT_DIR$/test/node_modules/express/lib/router\">\n      <RunnerSettings RunnerId=\"debuggableProgram\" />\n      <ConfigurationWrapper RunnerId=\"debuggableProgram\" />\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"DartCommandLineRunConfigurationType\" factoryName=\"Dart Command Line Application\">\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"DartUnitRunConfigurationType\" factoryName=\"DartUnit\">\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"JavaScriptTestRunnerKarma\" factoryName=\"Karma\" config-file=\"\">\n      <envs />\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"JSTestDriver:ConfigurationType\" factoryName=\"JsTestDriver\">\n      <setting name=\"configLocationType\" value=\"CONFIG_FILE\" />\n      <setting name=\"settingsFile\" value=\"\" />\n      <setting name=\"serverType\" value=\"INTERNAL\" />\n      <setting name=\"preferredDebugBrowser\" value=\"Chrome\" />\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"JavascriptDebugType\" factoryName=\"JavaScript Debug\">\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"NodeJSConfigurationType\" factoryName=\"Node.js\" working-dir=\"\">\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"cucumber.js\" factoryName=\"Cucumber.js\">\n      <option name=\"cucumberJsArguments\" value=\"\" />\n      <option name=\"executablePath\" />\n      <option name=\"filePath\" />\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"js.build_tools.gulp\" factoryName=\"Gulp.js\">\n      <node-options />\n      <gulpfile />\n      <tasks />\n      <pass-parent-envs>true</pass-parent-envs>\n      <envs />\n      <method />\n    </configuration>\n    <list size=\"3\">\n      <item index=\"0\" class=\"java.lang.String\" itemvalue=\"Node.js.server.js\" />\n      <item index=\"1\" class=\"java.lang.String\" itemvalue=\"Node.js.RESTcallsValidator.js\" />\n      <item index=\"2\" class=\"java.lang.String\" itemvalue=\"Node.js.route.js\" />\n    </list>\n    <recent_temporary>\n      <list size=\"3\">\n        <item index=\"0\" class=\"java.lang.String\" itemvalue=\"Node.js.server.js\" />\n        <item index=\"1\" class=\"java.lang.String\" itemvalue=\"Node.js.RESTcallsValidator.js\" />\n        <item index=\"2\" class=\"java.lang.String\" itemvalue=\"Node.js.route.js\" />\n      </list>\n    </recent_temporary>\n  </component>\n  <component name=\"ShelveChangesManager\" show_recycled=\"false\" />\n  <component name=\"SvnConfiguration\">\n    <configuration />\n  </component>\n  <component name=\"TaskManager\">\n    <task active=\"true\" id=\"Default\" summary=\"Default task\">\n      <changelist id=\"d9269681-97c6-4fc2-9aef-be25035f51df\" name=\"Default\" comment=\"\" />\n      <created>1426774221260</created>\n      <option name=\"number\" value=\"Default\" />\n      <updated>1426774221260</updated>\n    </task>\n    <servers />\n  </component>\n  <component name=\"ToolWindowManager\">\n    <frame x=\"1920\" y=\"-295\" width=\"1200\" height=\"1920\" extended-state=\"6\" />\n    <editor active=\"true\" />\n    <layout>\n      <window_info id=\"Changes\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"0\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Terminal\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"FLOATING\" visible=\"true\" weight=\"0.3298687\" sideWeight=\"0.5\" order=\"0\" side_tool=\"false\" content_ui=\"tabs\" x=\"490\" y=\"61\" width=\"1179\" height=\"840\" />\n      <window_info id=\"TODO\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"0\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Structure\" active=\"false\" anchor=\"left\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"0\" side_tool=\"true\" content_ui=\"tabs\" />\n      <window_info id=\"Application Servers\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"0\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Project\" active=\"false\" anchor=\"left\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"true\" weight=\"0.21289228\" sideWeight=\"0.5\" order=\"0\" side_tool=\"false\" content_ui=\"combo\" />\n      <window_info id=\"Debug\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.3298687\" sideWeight=\"0.5\" order=\"0\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Run\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.3298687\" sideWeight=\"0.5\" order=\"0\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Favorites\" active=\"false\" anchor=\"left\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"0\" side_tool=\"true\" content_ui=\"tabs\" />\n      <window_info id=\"Event Log\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"0\" side_tool=\"true\" content_ui=\"tabs\" />\n      <window_info id=\"Version Control\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"0\" side_tool=\"false\" content_ui=\"tabs\" />\n    </layout>\n    <layout-to-restore>\n      <window_info id=\"Changes\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"0\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Terminal\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"2\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"TODO\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"1\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Structure\" active=\"false\" anchor=\"left\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"0\" side_tool=\"true\" content_ui=\"tabs\" />\n      <window_info id=\"Application Servers\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"3\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Project\" active=\"false\" anchor=\"left\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"true\" weight=\"0.20747761\" sideWeight=\"0.5\" order=\"1\" side_tool=\"false\" content_ui=\"combo\" />\n      <window_info id=\"Debug\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"4\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Run\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"6\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Favorites\" active=\"false\" anchor=\"left\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"2\" side_tool=\"true\" content_ui=\"tabs\" />\n      <window_info id=\"Event Log\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"5\" side_tool=\"true\" content_ui=\"tabs\" />\n      <window_info id=\"Version Control\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"7\" side_tool=\"false\" content_ui=\"tabs\" />\n    </layout-to-restore>\n  </component>\n  <component name=\"Vcs.Log.UiProperties\">\n    <option name=\"RECENTLY_FILTERED_USER_GROUPS\">\n      <collection />\n    </option>\n    <option name=\"RECENTLY_FILTERED_BRANCH_GROUPS\">\n      <collection />\n    </option>\n  </component>\n  <component name=\"VcsContentAnnotationSettings\">\n    <option name=\"myLimit\" value=\"2678400000\" />\n  </component>\n  <component name=\"VcsManagerConfiguration\">\n    <option name=\"myTodoPanelSettings\">\n      <TodoPanelSettings />\n    </option>\n  </component>\n  <component name=\"XDebuggerManager\">\n    <breakpoint-manager>\n      <breakpoints>\n        <line-breakpoint enabled=\"true\" type=\"javascript\">\n          <url>file://$PROJECT_DIR$/test/node_modules/express-happiness/RESTcallsValidator.js</url>\n          <line>47</line>\n          <option name=\"timeStamp\" value=\"19\" />\n        </line-breakpoint>\n      </breakpoints>\n      <option name=\"time\" value=\"24\" />\n    </breakpoint-manager>\n    <watches-manager />\n  </component>\n  <component name=\"editorHistoryManager\">\n    <entry file=\"file://$PROJECT_DIR$/test/package.json\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"150\" max-vertical-offset=\"270\">\n          <caret line=\"10\" column=\"2\" selection-start-line=\"10\" selection-start-column=\"2\" selection-end-line=\"10\" selection-end-column=\"2\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/server.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"555\" max-vertical-offset=\"795\">\n          <caret line=\"37\" column=\"13\" selection-start-line=\"37\" selection-start-column=\"13\" selection-end-line=\"37\" selection-end-column=\"13\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/views/index.html\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"105\" max-vertical-offset=\"1185\">\n          <caret line=\"14\" column=\"0\" selection-start-line=\"14\" selection-start-column=\"0\" selection-end-line=\"14\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/conf/conf.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"45\" max-vertical-offset=\"195\">\n          <caret line=\"3\" column=\"0\" selection-start-line=\"3\" selection-start-column=\"0\" selection-end-line=\"3\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/conf/restConf.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"300\" max-vertical-offset=\"7020\">\n          <caret line=\"53\" column=\"44\" selection-start-line=\"53\" selection-start-column=\"32\" selection-end-line=\"53\" selection-end-column=\"44\" />\n          <folding>\n            <element signature=\"n#!!doc\" expanded=\"true\" />\n          </folding>\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/expressHappiness.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"5845\" max-vertical-offset=\"7110\">\n          <caret line=\"402\" column=\"20\" selection-start-line=\"402\" selection-start-column=\"20\" selection-end-line=\"402\" selection-end-column=\"20\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/errors.log\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"195\" max-vertical-offset=\"285\">\n          <caret line=\"13\" column=\"0\" selection-start-line=\"13\" selection-start-column=\"0\" selection-end-line=\"13\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/conf/errors.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"405\">\n          <caret line=\"0\" column=\"0\" selection-start-line=\"0\" selection-start-column=\"0\" selection-end-line=\"0\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/fieldsLoader.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"600\" max-vertical-offset=\"825\">\n          <caret line=\"40\" column=\"16\" selection-start-line=\"40\" selection-start-column=\"16\" selection-end-line=\"44\" selection-end-column=\"17\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/controllerFunctions.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"30\" max-vertical-offset=\"120\">\n          <caret line=\"2\" column=\"0\" selection-start-line=\"2\" selection-start-column=\"0\" selection-end-line=\"2\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/ErrorHandler.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"225\" max-vertical-offset=\"555\">\n          <caret line=\"15\" column=\"16\" selection-start-line=\"15\" selection-start-column=\"16\" selection-end-line=\"15\" selection-end-column=\"16\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/RESTcallsValidator.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"75\" max-vertical-offset=\"2790\">\n          <caret line=\"5\" column=\"8\" selection-start-line=\"5\" selection-start-column=\"7\" selection-end-line=\"5\" selection-end-column=\"8\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/package.json\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"375\" max-vertical-offset=\"465\">\n          <caret line=\"25\" column=\"1\" selection-start-line=\"25\" selection-start-column=\"1\" selection-end-line=\"25\" selection-end-column=\"1\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/package.json\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"150\" max-vertical-offset=\"270\">\n          <caret line=\"10\" column=\"2\" selection-start-line=\"10\" selection-start-column=\"2\" selection-end-line=\"10\" selection-end-column=\"2\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/server.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"660\" max-vertical-offset=\"795\">\n          <caret line=\"44\" column=\"0\" selection-start-line=\"44\" selection-start-column=\"0\" selection-end-line=\"44\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/conf/conf.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"45\" max-vertical-offset=\"195\">\n          <caret line=\"3\" column=\"0\" selection-start-line=\"3\" selection-start-column=\"0\" selection-end-line=\"3\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/expressHappiness.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"5557\" max-vertical-offset=\"6630\">\n          <caret line=\"422\" column=\"31\" selection-start-line=\"422\" selection-start-column=\"15\" selection-end-line=\"422\" selection-end-column=\"31\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/fieldsLoader.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"825\">\n          <caret line=\"0\" column=\"0\" selection-start-line=\"0\" selection-start-column=\"0\" selection-end-line=\"0\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/controllerFunctions.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"30\" max-vertical-offset=\"120\">\n          <caret line=\"2\" column=\"0\" selection-start-line=\"2\" selection-start-column=\"0\" selection-end-line=\"2\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/ErrorHandler.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"450\">\n          <caret line=\"0\" column=\"0\" selection-start-line=\"0\" selection-start-column=\"0\" selection-end-line=\"0\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/RESTcallsValidator.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"75\" max-vertical-offset=\"2790\">\n          <caret line=\"5\" column=\"8\" selection-start-line=\"5\" selection-start-column=\"7\" selection-end-line=\"5\" selection-end-column=\"8\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/package.json\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"375\" max-vertical-offset=\"465\">\n          <caret line=\"25\" column=\"1\" selection-start-line=\"25\" selection-start-column=\"1\" selection-end-line=\"25\" selection-end-column=\"1\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/package.json\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"150\" max-vertical-offset=\"270\">\n          <caret line=\"10\" column=\"2\" selection-start-line=\"10\" selection-start-column=\"2\" selection-end-line=\"10\" selection-end-column=\"2\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/server.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"660\" max-vertical-offset=\"795\">\n          <caret line=\"44\" column=\"0\" selection-start-line=\"44\" selection-start-column=\"0\" selection-end-line=\"44\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/conf/conf.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"45\" max-vertical-offset=\"195\">\n          <caret line=\"3\" column=\"0\" selection-start-line=\"3\" selection-start-column=\"0\" selection-end-line=\"3\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/expressHappiness.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"5557\" max-vertical-offset=\"6630\">\n          <caret line=\"422\" column=\"31\" selection-start-line=\"422\" selection-start-column=\"15\" selection-end-line=\"422\" selection-end-column=\"31\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/fieldsLoader.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"825\">\n          <caret line=\"0\" column=\"0\" selection-start-line=\"0\" selection-start-column=\"0\" selection-end-line=\"0\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/controllerFunctions.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"30\" max-vertical-offset=\"120\">\n          <caret line=\"2\" column=\"0\" selection-start-line=\"2\" selection-start-column=\"0\" selection-end-line=\"2\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/ErrorHandler.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"450\">\n          <caret line=\"0\" column=\"0\" selection-start-line=\"0\" selection-start-column=\"0\" selection-end-line=\"0\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/RESTcallsValidator.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"75\" max-vertical-offset=\"2790\">\n          <caret line=\"5\" column=\"8\" selection-start-line=\"5\" selection-start-column=\"7\" selection-end-line=\"5\" selection-end-column=\"8\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/package.json\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"150\" max-vertical-offset=\"270\">\n          <caret line=\"10\" column=\"2\" selection-start-line=\"10\" selection-start-column=\"2\" selection-end-line=\"10\" selection-end-column=\"2\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/package.json\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"180\" max-vertical-offset=\"480\">\n          <caret line=\"12\" column=\"24\" selection-start-line=\"12\" selection-start-column=\"24\" selection-end-line=\"12\" selection-end-column=\"24\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/views/index.html\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"105\" max-vertical-offset=\"1185\">\n          <caret line=\"14\" column=\"0\" selection-start-line=\"14\" selection-start-column=\"0\" selection-end-line=\"14\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/mockdata/getTraffic.json\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.008445946\" vertical-offset=\"0\" max-vertical-offset=\"1776\">\n          <caret line=\"1\" column=\"12\" selection-start-line=\"1\" selection-start-column=\"12\" selection-end-line=\"1\" selection-end-column=\"12\" />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/conf/errors.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"405\">\n          <caret line=\"11\" column=\"12\" selection-start-line=\"11\" selection-start-column=\"12\" selection-end-line=\"11\" selection-end-column=\"49\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/controllerFunctions.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"210\">\n          <caret line=\"4\" column=\"22\" selection-start-line=\"4\" selection-start-column=\"22\" selection-end-line=\"4\" selection-end-column=\"22\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/conf/restConf.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.5\" vertical-offset=\"0\" max-vertical-offset=\"1800\">\n          <caret line=\"60\" column=\"21\" selection-start-line=\"60\" selection-start-column=\"21\" selection-end-line=\"60\" selection-end-column=\"21\" />\n          <folding>\n            <element signature=\"n#!!doc\" expanded=\"true\" />\n          </folding>\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/conf/conf.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"240\">\n          <caret line=\"10\" column=\"0\" selection-start-line=\"10\" selection-start-column=\"0\" selection-end-line=\"10\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/expressHappiness.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"1815\" max-vertical-offset=\"8010\">\n          <caret line=\"137\" column=\"38\" selection-start-line=\"137\" selection-start-column=\"38\" selection-end-line=\"137\" selection-end-column=\"38\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/fieldsLoader.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.33333334\" vertical-offset=\"0\" max-vertical-offset=\"1800\">\n          <caret line=\"40\" column=\"16\" selection-start-line=\"40\" selection-start-column=\"16\" selection-end-line=\"44\" selection-end-column=\"17\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/node_modules/express/lib/router/layer.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"846\" max-vertical-offset=\"2580\">\n          <caret line=\"83\" column=\"0\" selection-start-line=\"83\" selection-start-column=\"0\" selection-end-line=\"83\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/node_modules/express/lib/router/route.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"996\" max-vertical-offset=\"2835\">\n          <caret line=\"93\" column=\"0\" selection-start-line=\"93\" selection-start-column=\"0\" selection-end-line=\"93\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/RESTcallsValidator.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.9749373\" vertical-offset=\"2763\" max-vertical-offset=\"4020\">\n          <caret line=\"262\" column=\"1\" selection-start-line=\"262\" selection-start-column=\"1\" selection-end-line=\"262\" selection-end-column=\"1\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/helpers/helpers.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"1800\">\n          <caret line=\"0\" column=\"0\" selection-start-line=\"0\" selection-start-column=\"0\" selection-end-line=\"0\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/errors.log\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.924812\" vertical-offset=\"498\" max-vertical-offset=\"1695\">\n          <caret line=\"107\" column=\"48\" selection-start-line=\"107\" selection-start-column=\"48\" selection-end-line=\"107\" selection-end-column=\"48\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/reusableFields.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"540\" max-vertical-offset=\"3585\">\n          <caret line=\"33\" column=\"30\" selection-start-line=\"33\" selection-start-column=\"16\" selection-end-line=\"33\" selection-end-column=\"30\" />\n          <folding>\n            <element signature=\"n#!!doc\" expanded=\"true\" />\n          </folding>\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/node_modules/express-happiness/RESTcallsValidator.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"306\" max-vertical-offset=\"4020\">\n          <caret line=\"47\" column=\"0\" selection-start-line=\"47\" selection-start-column=\"0\" selection-end-line=\"47\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/node_modules/express-happiness/expressHappiness.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"6363\" max-vertical-offset=\"8010\">\n          <caret line=\"449\" column=\"15\" selection-start-line=\"449\" selection-start-column=\"8\" selection-end-line=\"449\" selection-end-column=\"15\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/server.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"795\">\n          <caret line=\"37\" column=\"15\" selection-start-line=\"37\" selection-start-column=\"15\" selection-end-line=\"37\" selection-end-column=\"15\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/test/node_modules/express-happiness/ErrorHandler.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"675\">\n          <caret line=\"20\" column=\"0\" selection-start-line=\"0\" selection-start-column=\"0\" selection-end-line=\"39\" selection-end-column=\"30\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/ErrorHandler.js\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.48872182\" vertical-offset=\"0\" max-vertical-offset=\"1197\">\n          <caret line=\"39\" column=\"30\" selection-start-line=\"39\" selection-start-column=\"30\" selection-end-line=\"39\" selection-end-column=\"30\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n  </component>\n</project>"
  },
  {
    "path": "ErrorHandler.js",
    "content": "var ErrorHandler = function(logfileUrl){\n    var fs = require('fs');\n    var moment = require('moment');\n\n    this.handleError = function(erObj, err, req, res){\n        var apipath = '';\n        if(req.expressHappiness){\n            apipath = req.expressHappiness.apipath;\n        }\n\n        var toAppend = '\\n' + moment().format('YYYY-MM-DD HH:mm:ss') + \" | \" + err.type + \" | \" + apipath + ' | ' + erObj.humanReadable;\n        if(err.details){\n            toAppend += ' | ' + JSON.stringify(err.details);\n        }\n\n        if(erObj.log){\n            fs.appendFile(logfileUrl, toAppend, function (er) {\n            });\n        }\n\n\n        if(erObj.hooks != null && erObj.hooks != undefined){\n            for(var i=0; i<erObj.hooks.length; i++){\n                hooks[i](req, erObj, err);\n            }\n        }\n\n        var toSend = erObj.sendToClient.data;\n        if(erObj.sendToClient){\n            if(erObj.sendToClient.data){\n                if(erObj.sendToClient.data === 'err.details'){\n                    toSend = err.details;\n                }\n            }\n        }\n        res.status(erObj.sendToClient.code || 200).send(toSend || '');\n    };\n}\n\nmodule.exports = ErrorHandler;"
  },
  {
    "path": "README.md",
    "content": "Express Happiness\n=================\n\nIntro\n-----\nExpressHappiness is a rich framework for creating web apps and services, built on top of \nthe [Express framework](http://expressjs.com/).\n\nWe all use and love Express. When it comes to large and complex apps, some times the \nmaintainability of them becomes hard as we keep on adding routes, handle errors and permissions.\n\nExpressHappiness provides a way to develop robust and maintainable apps or REST APIs using Express.\n\nThe main features of the framework are:\n\n* The full routes tree is defined in a single object, in a JSON-like manner\n* Error handling is defined in the exact same manner in a single file. You can either define your own error codes or define the way that they'll be handled in the errors configuration file and trigger them any time from any part of your code, letting the framework handle them the way you define.\n* Define permissions to each route by specifying the access group(s) that each route belongs to and define middlewares for groups of routes, not for each route separately\n* Validate the params of each call by defining their characteristics on the routes definition file\n* Automatically generate your rest api documentation\n* Work with mock data, by just putting a file in a specific folder and setting the `mock` parameter to true on the route's definition\n* Add function hooks to any error type\n* and many more...\n\n\nLicense\n-------\nReleased under the [WTFPL](http://sam.zoy.org/wtfpl/) license by Andreas Trantidis [@AndreasTrantidi](https://twitter.com/AndreasTrantidi)\n\n\n<h2>Install</h2>\n<code>\n$ npm install express-happiness\n</code>\n\n<h2>The basics / Structure</h2>\nEvery ExpressHappiness project consists of a specific set of files that define the project's routes and behaviour.\nThese files are:\n<ul>\n<li><b>Routes Tree Configuration</b>: On this file you'll put / define all\nof the supported routes of your app with all of their details. These details include the method of the route\n(get / post / put / delete), the parameters of the route (parameter type, validation rules) and you can also enable / disable\nthe mock operation.<br/>\nFor each route you can define an alias name and also the group(s) that this route belongs to. The \"groups\" that the\nroutes belong to are custom groups, with custom names. The groups that a route belongs to define the middlewares that\nwill be applied to it. More details about grouping and group-specific middlewares will be defined later on.\n</li>\n<li><b>Reusable Params File</b>: There are cases where many routes have the exact same parameter, with the\n exact same type and validation rules. In order to avoid rewriting the same parameter definition again and\n again throughout all of these routes you can define these params once and just reuse them to any of the routes. The file\n that holds the \"reusable params\" definitions is the Reusable Params File.\n These type of parameters are called \"reusable\" params and are defined on the Reusable Fields File</li>\n<li><b>Error Handling Configuration File</b>: At any point of the middlewares chain of any call you can\n trigger errors. Errors of custom types, decorated with custom details. Express Happiness provides an error handling\n mechanism that automatically takes care this errors. The way each custom type's error will be handled is defined on this file.\n The developer has the ability to define whether and what is going to be written to the error.log file,\n what code should be sent back to the client (200, 400, 401, etc) and what data will be served. Finally, on each of these\n error types, the developers can define a set of hook functions to be executed (email send, log to db, whatever).<br/>\n All these error handling parameters are defined on the Error Handling Configuration File.</li>\n<li><b>error log</b>: Is just a plain text file holding all logs printed out by the Error Handling mechanism</li>\n<li><b>Controller Functions</b>: This file defines the function that should be executed on each route.\n The main concept here is not to define / write the body of these functions within this file but to have a \"mapper\"\n endpoint though which anyone can easily find out what's going on, on any route.<br/>\n The association between routes and controller functions is done by an associative array,\n each key of which is a string, either the full route definition or the route alias and each value the corresponding controller function.\n As mentioned, routes' aliases can be defined on the Routes Tree Configuration File.</li>\n</ul>\n\n<h2>Starting with it</h2>\nIn order to start, you can just clone <a href=\"https://github.com/andreas-trad/express-happiness-quick-start\" target=\"_blank\">this repo</a> to your machine or either follow step\n by step this document.\n<h3>Create your Reusable Params File</h3>\nEach route expects for some params to be passed on call. As mentioned, Express Happiness includes an automatic params\nvalidation mechanism and the only thing you should do is to define the params and the validation rules that apply for\neach route. <br/>\nEach parameter, no matter its type, has the following structure:<br/>\n<p>Code Snippet 1. <b>Parameter's basic structure</b></p>\n<pre lang=\"javascript\"><code>\nparam: {\n    \"key\": \"the-key-name\",\n    \"type\": \"one-of-the-supported-types\",\n    \"humanReadable\": \"short title of the param\",\n    \"description\": \"A human-readable description of the parameter\",\n    \"mandatory\": \"boolean-true-or-false\"\n}\n</code></pre>\n<br/>\nNot all of these characteristics are mandatory nor are they all. For each parameter type, special characteristics apply.\nFor example, for type \"int\", the definition object of the param may (optionally) include \"min\" and \"max\" keys, etc.<br/>\n<br/><b>The list of the supported parameter types is:</b>\n<p>Table 1. <b>Supported parameter types</b></p>\n<table>\n<tr>\n<td>int</td>\n<td>Integer</td>\n</tr>\n<tr>\n<td>date</td>\n<td>Date</td>\n</tr>\n<tr>\n<td>oneof</td>\n<td>The value must be one of the specified</td>\n</tr>\n<tr>\n<td>boolean</td>\n<td>Boolean</td>\n</tr>\n<tr>\n<td>numeric</td>\n<td>any number</td>\n</tr>\n<tr>\n<td>string</td>\n<td>String</td>\n</tr>\n<tr>\n<td>array</td>\n<td>Array</td>\n</tr>\n<tr>\n<td>object</td>\n<td>Object</td>\n</tr>\n</table>\n\n<b>The full list of the supported attributes for each param are listed below:</b>\n<p>Table 2. <b>Supported param attrs</b></p>\n<table>\n<thead>\n<tr>\n<th>Attribute key</th>\n<th>Mandatory</th>\n<th>Description</th>\n<th>Applies to</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>key</td>\n<td>yes</td>\n<td>the key name of the parameter. For example, if on a route you expect for a param with the name \"x\", then the key\nof this param is \"x\"</td>\n<td>all types</td>\n</tr>\n<tr>\n<td>type</td>\n<td>yes</td>\n<td>the type of the parameter. Might be one of: \"int\", \"date\", \"oneof\", \"boolean\", \"numeric\", \"string\", \"array\" and \"object\"</td>\n<td></td>\n</tr>\n<tr>\n<td>humanReadable</td>\n<td>no</td>\n<td>a short title of the parameter. This is used by the parameters validator on the error texts that exports on validation failures</td>\n<td>all types</td>\n</tr>\n<tr>\n<td>description</td>\n<td>no</td>\n<td>the description of the parameter. It will be used on the auto-generated documentation of your API</td>\n<td>all types</td>\n</tr>\n<tr>\n<td>mandatory</td>\n<td>no</td>\n<td>defines whether the parameter is mandatory or not. If it's missing the parameter is not mandatory</td>\n<td>all types</td>\n</tr>\n<tr>\n<td>validationFailureTexts</td>\n<td>no</td>\n<td>An object containing the text messages that will sent back to the client for all (or any) cases that the validation fails. For example,\nif a mandatory field is missing the text that will be sent back to the client is defined on the key \"mandatory\" of this object, etc. The\nsupported keys of this object are listed on the very next table that follows.</td>\n<td>all types</td>\n</tr>\n<tr>\n<td>min</td>\n<td>no</td>\n<td>the minimum value (including this) that a param can accept</td>\n<td>int, numeric</td>\n</tr>\n<tr>\n<td>max</td>\n<td>no</td>\n<td>the maximum value (including this) that a param can accept</td>\n<td>int, numeric</td>\n</tr>\n<tr>\n<td>minChars</td>\n<td>no</td>\n<td>the minimum characters that a string's type parameter's value might have</td>\n<td>string</td>\n</tr>\n<tr>\n<td>maxChars</td>\n<td>no</td>\n<td>the maximum characters that a string's type parameter's value might have</td>\n<td>string</td>\n</tr>\n<tr>\n<td>validationString</td>\n<td>yes</td>\n<td>the format that a date value should have. The formats are identical as on moment.js</td>\n<td>date</td>\n</tr>\n<tr>\n<td>minLength</td>\n<td>no</td>\n<td>the minimum length an array-type value should have</td>\n<td>array</td>\n</tr>\n<tr>\n<td>maxLength</td>\n<td>no</td>\n<td>the maximum length an array-type value should have</td>\n<td>array</td>\n</tr>\n<tr>\n<td>acceptedValues</td>\n<td>yes</td>\n<td>an array listing all the acceptable values for this param</td>\n<td>oneof</td>\n</tr>\n<tr>\n<td>regexp</td>\n<td>no</td>\n<td>a regular expression to check the provided value against</td>\n<td>string</td>\n</tr>\n<tr>\n<td>keys</td>\n<td>no</td>\n<td>an object that specifies the expected structure of an object type parameter</td>\n<td>object</td>\n</tr>\n</tbody>\n</table>\n\n<b>The supported keys of the validationFailureTexts are:</b>\n<p>Table 3. <b>validationFailureTexts supported attributes</b></p>\n<table>\n<thead>\n<tr>\n<th>Key</th>\n<th>In case...</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>type</td>\n<td>the type of the field's value is not of the defined/expected field's type</td>\n</tr>\n<tr>\n<td>mandatory</td>\n<td>a mandatory filed is missing</td>\n</tr>\n<tr>\n<td>min</td>\n<td>the either of type int or numeric field's value is lower than the minimum accepted, according to the min attribute of the field's definition</td>\n</tr>\n<tr>\n<td>max</td>\n<td>the either of type int or numeric field's value is greater than the maximum accepted, according to the max attribute of the field's definition</td>\n</tr>\n<tr>\n<td>minChars</td>\n<td>the characters of the provided string are less than the minimum accepted, according to the minChars attribute of the field's definition</td>\n</tr>\n<tr>\n<td>maxChars</td>\n<td>the characters of the provided string are more than the maximum accepted, according to the maxChars attribute of the field's definition</td>\n</tr>\n<tr>\n<td>validationString</td>\n<td>the value provided for the field of type date is not compatible with the validationString of the field's definition</td>\n</tr>\n<tr>\n<td>minLength</td>\n<td>the length of the array passed on the specific field's value is lower than the minimum accepted, according to the minLength attribute of the field's definition</td>\n</tr>\n<tr>\n<td>maxLength</td>\n<td>the length of the array passed on the specific field's value is greater than the maximum accepted, according to the maxLength attribute of the field's definition</td>\n</tr>\n<tr>\n<td>acceptedValues</td>\n<td>the value of the, of type oneof, field is not present on the acceptedValues array on the field's definition</td>\n</tr>\n<tr>\n<td>regexp</td>\n<td>the string provided does not comply with the regular expression from the regexp property of the field's definition</td>\n</tr>\n</tbody>\n</table>\n\nSo, as an example:\n<p>Code Snippet 2. <b>Parameter's structure including validationFailureTexts object</b></p>\n<pre lang=\"javascript\"><code>\nparam: {\n    \"key\": \"user_age\",\n    \"type\": \"int\",\n    \"humanReadable\": \"Age\",\n    \"description\": \"The age of the user\",\n    \"mandatory\": \"true\",\n    \"min\": 18,\n    \"validationFailureTexts\": {\n        \"mandatory\": \"Please provide your age\",\n        \"min\": \"Sorry, you must be at least 18 years old\"\n    }\n}\n</code></pre>\n\nIn such case if the submitted value for the \"age\" is under 18 (let's say 17) then on the \"errors\" array of the response there will be the\ntext \"Sorry, you must be at least 18 years old\". If the key \"min\" was missing from the \"validationFailureTexts\" object (of if\nthe \"validationFailureTexts\" was missing at all on the field's definition), the error text that would be included on the errors array would be the default:\n\"Age must be greater or equal to 18. 17 provided.\"<br/>\nFinally, in the case that there was the \"humanReadable\" key missing from the field's definition, then the error text would be:\n\"user_age must be greater or equal to 18. 17 provided.\"\n<p>\nNow it's time to proceed with your Reusable Params File.<br/>\nThe reusable params file is just a module that exports an object. This object has a number of keys. Each\nkey holds another object which represents the definition of a parameter. <br/>\nThe name of the key is the way you'll refer to the parameter from the Routes Tree Configuration File.<br/>\nSo, let's assume that you want to define two reusable parameters on this file, parameter \"id\" and parameter\n\"cat_id\". Here's a possible / valid definition of these two params in the Reusable Params File:\n<p>Code Snippet 3. <b>Example of Reusable Params File</b></p>\n<pre lang=\"javascript\"><code>\nmodule.exports = {\n    id:{\n        key:'id',\n        type:'int',\n        humanReadable: 'organization id',\n        description:'The Organization from which data is requested',\n        mandatory:true\n    },\n    category: {\n        key:'cat_id',\n        type:'oneof',\n        humanReadable: 'Product category',\n        description:'The category of the product',\n        mandatory:false,\n        acceptedValues: ['shoes', 'clothes'],\n        validationFailureTexts: {\n            acceptedValues: 'Sorry, only shoes or clothes categories are supported'\n        }\n    }\n}\n</code></pre>\nPay attention that we have a unique name for each parameter defined here, which is the key of the\nexported module. This name will be used in the Routes Tree Configuration File in order to load and\ndefine the parameters that each route will expect for. <br/>\nThough, each of these params have a \"key\" attribute. This is the name of the parameter as we expect it\nduring the actual calls that our service will receive.\n</p>\n\n<h3>Defining object type params</h3>\nAs mentioned, one of the supported param types is the \"object\". Also, one of the supported on object-type parameter's attributes\nis \"keys\".<br/>\nYou can use the \"keys\" attribute of an object parameter in order to define (to any depth) the expected structure of the object\nand not only this. You can apply / define validation rules of each of them, no matter which depth it is. Here's an example:<br/>\nLet's suppose that on a specific call we expect for a parameter with the name \"user_data\" which will hold the user's information\nin a well defined structure. Both the structure of the expected object and the validation rules that apply to it are made\nobvious through the following parameter definition:\n<p>Code Snippet 4. <b>Example of an object parameter</b></p>\n<pre lang=\"javascript\"><code>\nuser:{\n    key:'user_data',\n    type:'object',\n    humanReadable:'User data',\n    description:'Full user information',\n    mandatory:true,\n    keys:{\n        gender:{\n            type:'oneof',\n            mandatory:true,\n            acceptedValues: ['male', 'female'],\n            validationFailureTexts: {\n                mandatory: 'Please specify your gender',\n                acceptedValues: 'Please pick between male and female'\n            }\n        },\n        country:{\n            type:'oneof',\n            acceptedValues:['Greece', 'Sweden', 'Australia', 'Romania']\n        },\n        name:{\n            type:'object',\n            keys:{\n                first:{\n                    mandatory:true,\n                    type:'string'\n                },\n                last:{\n                    mandatory:true,\n                    type:'string',\n                    validationFailureTexts: {\n                        mandatory: 'Please specify your last name'\n                    }\n                },\n                middle: {\n                    mandatory: false,\n                    type: 'string'\n                }\n            }\n        }\n    }\n}\n</code></pre>\nSo, as you can see, not only we define the structure of the expected object but we can define the validation rules that might\napply to any of the keys of the object. Please mention that the \"name\" key is an object itself and it also contains the \"keys\"\nparameter which holds the information regarding the expected keys of it. There's no limit on the depth of the nested objects\nand parameters.<br/>\nThe \"keys\" param is an object which holds a set of keys. These keys represent / map the expected keys of the object.<br/>\nThe attributes of each one of these keys are identical with the attributes used in plain (not-object) parameters. All attributes\nof table 2 apply just fine to all nested keys of all objects. The only difference between the definition of a plain parameter\nand the definition of an object's key is that on the object key's definition there's no \"key\" attribute. The \"key\", that is\nthe expected name of the key on the provided object during a call, is identical to the name of the key itself. E.g. on the\nspecific example we expect the user_data.name.first to be present.<br/>\nThis has been implemented this way for two reasons:\n<ul>\n<li>There's no need and no way to refer to a nested key from services such as the FieldsLoader (we'll see about that later on)</li>\n<li>We wanted to mimic the structure of the object in an one-to-one mapping</li>\n</ul>\nDuring the parameters validation process, which we'll analyse on following chapter, the full object is been validated according\nto the definition of it. Don't worry this process is 100% asynchronous, so you can go ahead and create as deep, as long and\nas complex object parameter definitions. It won't block your app during validation.\n\n<h2>Routes Tree Configuration File</h2>\nNow that we've defined the parameters that we're going to (re)use on our endpoints, it's time to define\nthese calls. <i>Of course you can always come back to the Reusable Params File and update it with new\nones.</i>\nAll of the supported routes of our application are defined in this very file. <br/>\nIn order to be able to reuse the parameters we defined in the Reusable Params File, we need the (built in) FieldsLoader\nmodule. For this the structure / format of our Routes Tree Configuration File should look like this:\n<p>Code Snippet 5. <b>Basic structure of the Routes Tree Configuration File</b></p>\n<pre lang=\"javascript\"><code>\nmodule.exports.conf = function(fieldsLoader){\n    return {\n        routes:{\n            // here go all of the supported routes of the application\n        }\n    }\n};\n</code></pre>\n\nYou might have noticed the term \"Tree\" in the name of the \"Routes Tree Configuration File\". Before further analysing the\nway we can define your routes in here, it's good to mention a few things regarding its concept.<br/>\nIn an application there might be routes of the same url (e.g. /a/b) but of different types (e.g. GET, POST). Also, in\nan application there might be routes that do something and also subroutes of it that do something else. For example,\nthere might be the route /a/b and also the route /a/b/c.<br/>\nThe way the routes are defined on the Routes Tree Definition File respect both of the above facts. On any given path you\ncan separately define the various supported call types and then you can continue deeper defining the supported subroutes of it.<br/>\nIn the specific example here's a possible / valid Routes Tree Configuration File:\n<p>Code Snippet 6. <b>Routes Tree Configuration File including paths and endpoints</b></p>\n<pre lang=\"javascript\"><code>\nmodule.exports.conf = function(fieldsLoader){\n    return {\n        routes:{\n            a:{\n                subRoutes: {\n                    b: {\n                        get: {\n                            // here goes the GET /a/b route definition\n                        },\n                        post: {\n                            // here goes the POST /a/b route definition\n                        },\n                        subRoutes: {\n                            c: {\n                                get: {\n                                    // here goes the GET /a/b/c route definition\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n};\n</code></pre>\n\nIn general, the tree that we are defining here consists of paths and endpoints. Everything starts on the \"routes\" parameter\nof the returned object. \"a\" represents a path, the path \"/a\". This path has subRoutes, like \"/a/b\". So, we define these\nsubroutes on the \"subRoutes\" parameter of it.<br/>\n\"b\" is a path itself as well. Following the object's structure, is obvious that it represents the path \"/a/b\". A path might\nhave (or might not have) endpoints. For example the path \"/a\" does not have any endpoints. Though, path \"/a/b\" has get and post\nendpoints. <br/>\nThe endpoints are defined by the use of the corresponding key (one of \"get\", \"post\", \"put\", \"delete\"). The endpoints are the \"leafs\"\nof this tree while the paths act as the branches.<br/>\nA branch can have sub-branches and leafs. A leaf cannot have neither sub-branches nor sub-leafs, and that's we call then \"endpoints\".<br/>\nWithin the \"subRoutes\" parameter of any path we can only define paths.<br/>\nOn any endpoint we can define the fields that we're expecting.<br/>\nHere's a table with all the supported attributes of each element:\n<p>Table 4. <b>Path's supported attributes</b></p>\n<table>\n<thead>\n<tr>\n<th>Attribute name</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>groups</td>\n<td>an array containing all the groups the path belongs to</td>\n</tr>\n<tr>\n<td>subRoutes</td>\n<td>an object which keys will represent the next sub-section of the path</td>\n</tr>\n<tr>\n<td>any of the supported call types (one of \"get\", \"post\", \"put\", \"delete\")</td>\n<td>defines an endpoint to the specific path. E.g. by placing the \"get\" key on a path it's value must be an object defining\nthe characteristics of the specific endpoint</td>\n</tr>\n</tbody>\n</table>\n\n<p>Table 5. <b>Endpoints's supported attributes</b></p>\n<table>\n<thead>\n<tr>\n<th>Attribute name</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>groups</td>\n<td>an array containing all the groups the path belongs to</td>\n</tr>\n<tr>\n<td>alias (optional)</td>\n<td>a string representation / alias name of the specific endpoint</td>\n</tr>\n<tr>\n<td>description (optional)</td>\n<td>a human readable description of the endpoint. This will be used on the auto-generated documentation of your API</td>\n</tr>\n<tr>\n<td>fields (optional)</td>\n<td>an array containing all the fields that are expected on this endpoint. It will be used both by the validator and the\nauto-generated documentation process. If your endpoint does not expect any parameters or you don't want to apply any\nparams validation you can just skip it</td>\n</tr>\n<tr>\n<td>mock</td>\n<td>in cases you want a specific endpoint to serve mock data just put the mock attribute and set it to true</td>\n</tr>\n</tbody>\n</table>\n\n<h3>Groups</h3>\nBoth on tables 4 and 5 you might have noticed the \"groups\" attribute. The \"groups\" attribute helps us organize / categorize\nall of our endpoints into categories / groups.<br/>\nThe grouping mechanism follows a waterfall inheritance mechanism, just like inheritance works on html elements. Every child inherits\nby default the groups of its closest parent. If its closest parent has no group definition then that means it inherits its own\nclosest parent's groups etc.<br/>\nFor any element in our tree (either endpoint or path), this inheritance goes all the way up until we have an explicit groups definition.<br/>\nSo if you have endpoints / routes defined on /admin/* and all belong to a specially restricted area of your application, where\nadmin authentication should take place, the only thing you have to do is to define on the /admin path the groups equal to ['admin']. All\nof the child paths and endpoints of it will inherit this groups definition. <br/>\nAt any point, at any path or endpoint, you can explicitly define the groups attribute. By this way, any inherited value of the\nattribute \"groups\" will be ignored and the explicitly defined will prevail.<br/>\nBy organizing the endpoints into groups on the Routs Tree Configuration File gives us the opportunity apply middlewares\nspecially developed for each of these groups. We'll see more details on this later on.<br/>\nFinally, as you might have noticed, groups is an array. That means that for an endpoint belonging to more than one groups,\nall middlewares of all groups it belongs to will be applied in the sequence the group names have been placed within the array.\n\n<h3>Alias / Mock operation</h3>\nThe \"alias\" attribute of each endpoint gives us a way to refer to this endpoint from any other part of the Express Happiness\necosystem. The most important usage of this \"alias\" has to do with the mock operation. As mentioned on table 5, along with the\n\"alias\" attribute each endpoint (optionally, default = false) might have a \"mock\" attribute set to true. <br/>\nWe will analyse mock operation in details in a following part of this document, though keep just one thing in mind for now.\nIf any of the endpoints has been set to server mock data then a file containing the mock response should be present somewhere in\nyour hard drive. The folder that contains all mock files is defined on ExpressHappiness invocation, though the actual name\nof the file, for each endpoint, should be identical with its alias.\n\n<h3>fields</h3>\nThe fields is an array containing all the fields that the specific endpoint supports / expects. As explained, all of the\nfields / params have a very specific definition pattern that has been analyzed on the Reusable Params File section. <br/>\nThe fields array might \"load\" fields from the reusable fields or can either include newly defined params.<br/>\nIn order to load a parameter from the params defined on the Reusable Params File you should use the method \"getField\" of the\nFieldsLoader module that comes with the ExpressHappiness framework. <br/>\nHere is a complete example, using the fields defined on code snippet 3:\n<p>Code Snippet 7. <b>Routes Tree Configuration File example with fields loading</b></p>\n<pre lang=\"javascript\"><code>\nmodule.exports.conf = function(fieldsLoader){ // mind the \"fieldsLoader\" argument\n    return {\n        routes:{\n            a:{\n                subRoutes: {\n                    b: {\n                        get: {\n                            alias: 'a_b_get',\n                            description: 'a dummy description of a dummy endpoint',\n                            fields: [\n                                fieldsLoader.getField('id'),\n                                fieldsLoader.getField('category', {\n                                    mandatory:true\n                                }),\n                                {\n                                    key: 'size',\n                                    mandatory: true,\n                                    type: 'numeric'\n                                }\n                            ]\n                        }\n                    }\n                }\n            }\n        }\n    }\n};\n</code></pre>\n\nAs you can see, on the GET \"/a/b\" endpoint we have defined three fields:\n<ul>\n<li><b>by loading the \"id\" field.</b> The resulting field is identical as the definition of the field on the Reusable Params File (code snippet 3)</li>\n<li><b>by loading the \"category\" field and passing second argument on getField.</b> The \"getField\" method of FieldsLoader takes a second optional\nattribute. This attribute is an object. All own keys of this object that are included in the supported params attrs list (table 2) will overwrite the\nones defined on the Reusable Params File.</li>\n<li><b>A totally new parameter.</b> There are cases where a parameter might appear only once and only in one endpoint. In such cases there's\nabsolutely no need to define it on the Reusable Params File but, instead, you can define it directly on the \"fields\" array of the endpoint.</li>\n</ul>\n\n<h3>Dynamic routes</h3>\nA question that arises has to do with the dynamic routes (e.g. \"/a/b/:c\"). This is of course supported by ExpressHappiness\nand you can totally use it on your Routes Tree Configuration File. You can access these fields as you would usually do through\nthe <a href=\"http://expressjs.com/api.html#req\" target=\"_blank\">req object</a> of express.</br>\nHere's a simple demonstration on how to define routes including dynamic params:\n\n<p>Code Snippet 8. <b>Dynamic Route Params</b></p>\n<pre lang=\"javascript\"><code>\nmodule.exports.conf = function(fieldsLoader){ // mind the \"fieldsLoader\" argument\n    return {\n        routes:{\n            a:{\n                subRoutes: {\n                    \":b\": { // check the \":b\" on the subRoute key\n                        get: {\n                            // endpoint definition\n                        }\n                    }\n                }\n            }\n        }\n    }\n};\n</code></pre>\n\n<h2>Error Handling and Error Handling Configuration File</h2>\nThe way errors are handled by Express Happiness is centralized and configurable. All errors, including the unknown, are\nhandled by the framework itself and the developer has the ability to configure the behaviour of the app in each error type.\nExpress Happiness also provides the ability to define custom error types, define the behaviour of the app in each of them,\ntrigger such errors from anywhere in your middlewares chain and let the framework take care of them accordingly.<br/>\nThe way each error type should be treated by the application is defined on the Error Handling Configuration File.\n<br/>The basic structure of this file is the following:\n<p>Code snippet 9. <b>Error Handling Configuration File Basic Structure</b>\n<pre language=\"javascript\"><code>\nexports.errors = {\n    undefinedError:{\n        log:true,\n        humanReadable: 'Unresolved error code',\n        sendToClient: {\n            code:500,\n            data: 'ErrCode: 1 - There was an error fulfilling your request at the moment. Please try again in a while'\n        },\n        hooks:[\n            // here you can put whatever you want\n        ]\n    },\n    '404':{\n        log:true,\n        sendToClient: {\n            code:404,\n            data:'Invalid route'\n        }\n    },\n    'my_custom_error_code':{\n        log:false,\n        sendToClient:{\n            code:500,\n            data:'There was an error fulfilling your request'\n        }\n    }\n}\n</code></pre>\n\nThe Error Handling Configuration File exports an object. Each object key represents the \"type\" of the error. So, in our\nexample, if an undefined error gets triggered by the app, our application will log it, it will write to the log file the\ntext \"Unresolved error code\" and the client will receive a 500 code along with the body \"ErrCode: 1 - There was an error\nfulfilling your request at the moment. Please try again in a while\".</br>\nLet's dive deeper and see which attributes are supported for each error type defined on this file.\n<p>Table 6. <b>Supported attributes on error configuration</b></p>\n<table>\n<thead>\n<tr>\n<th>Attribute name</th>\n<th>Type</th>\n<th>Mandatory</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>log</td>\n<td>boolean</td>\n<td>no (default: false)</td>\n<td>If log is set to true, this error will be logged to the error.log file</td>\n</tr>\n<tr>\n<td>humanReadable</td>\n<td>string</td>\n<td>no</td>\n<td>a human readable description of the error. This is what it will get logged to the error.log file if log is set to true</td>\n</tr>\n<tr>\n<td>sendToClient</td>\n<td>object with two keys: code and data</td>\n<td>no</td>\n<td>with the use of this attribute you can define the response code and the response body that will be sent back to the client. If you\nwant to send to the client the details of the error object just put there (in quotes) 'err.details'</td>\n</tr>\n<tr>\n<td>hooks</td>\n<td>array</td>\n<td>no</td>\n<td>a list of functions to be executed whenever an error of this type occurs. The hook functions should take 3 arguments:\n<ul>\n<li>req (the req object)</li>\n<li>errorDefinitionObject (the error definition object taken from the Error Handling Configuration File)</li>\n<li>err (the actual error triggered during the call stack)</li>\n</ul>\nThese hook functions get executed before your app responds to the client they are not part of the calls chain (they do not\nact as middlewares)\n</td>\n</tr>\n</tbody>\n</table>\n\n<h3>Triggering Errors</h3>\nOnce you define all of your error on the Error Handling Configuration File you can at any time, from anywhere on your code\ntrigger any of these by the use of this, simple, code:\n<p>Code Snippet 10. <b>Triggering errors</b></p>\n<pre language=\"javascript\"><code>\nvar err = new Error();\nerr.type = 'my_custom_error';\nerr.details = 'The details of the error. Might be either a string, such as this, or any other data type (object, array etc)';\nreturn next(err);\n</code></pre>\n\nIn order for this part of code to work you must have the \"next\" function available.\nFot those who are not that familiar with \"next\" function, please have a look <a href=\"http://expressjs.com/guide/using-middleware.html\" target=\"_blank\">here</a>.\n<br/>Once you trigger this event the rest is on Express Happiness to take care of, according to the Error Handling Configuration File.\n\n<h3>Predefined Errors</h3>\nExpress Happiness comes with a series of error types predefined. These are:\n<ul>\n<li><b>undefinedError</b> It's triggered for errors that don't belong to any of the defined errors. It's default configuration\nis: <br/>\n<p>Code Snippet 11.1. <b>Default undefinedError configuration</b></p>\n<pre language=\"javascript\"><code>\n{\n    log:true,\n    humanReadable: 'Unresolved error code',\n    sendToClient: {\n        code:500\n    }\n}\n</code></pre>\n</li>\n\n<li><b>invalidAttrs</b> It's triggered on parameters validation failure. It's default configuration\nis: <br/>\n<p>Code Snippet 11.2. <b>Default invalidAttrs configuration</b></p>\n<pre language=\"javascript\"><code>\n{\n    log:true,\n    humanReadable: 'Invalid attributes passed',\n    sendToClient: {\n        code:400,\n        data:'err.details'\n    }\n}\n</code></pre>\n</li>\n\n<li><b>404</b> It's triggered whenever a route does not exist. It's default configuration\nis: <br/>\n<p>Code Snippet 11.3. <b>Default 404 configuration</b></p>\n<pre language=\"javascript\"><code>\n{\n    log:false,\n    humanReadable: 'The requested resource does not exist',\n    sendToClient: {\n        code:404\n    }\n}\n</code></pre>\n</li>\n\n<li><b>noMockData</b> It's triggered whenever a route that is defined to serve mock data, does not have any mock data file.\nIt's default configuration\nis: <br/>\n<p>Code Snippet 11.4. <b>Default noMockData configuration</b></p>\n<pre language=\"javascript\"><code>\n{\n    log: true,\n    humanReadable: 'There is no mock data available for this route yet',\n    sendToClient: {\n        code: 404,\n        data:'There is no mock data available for this route yet'\n    }\n}\n</code></pre>\n</li>\n\n<li><b>underDevelopment</b> It's triggered in cases there's no controller function defined for a specific route.\nIt's default configuration is:<br/>\n<p>Code Snippet 11.5. <b>Default underDevelopment configuration</b></p>\n<pre language=\"javascript\"><code>\n{\n    log: false,\n    humanReadable: 'A call to a route under development has been made',\n    sendToClient:{\n        code:501,\n        data:'This route is currently under development'\n}\n</code></pre>\n</li>\n</ul>\nThe default behaviour on any of these errors can be altered by redefining them on the Error Handling Configuration File.\n\n<h3>error.log file</h3>\nAs mentioned earlier in this document, Express Happiness logs errors on an error log file. This file is defined on application\nstart. Express Happiness does not log all the errors but only those which have log:true on their definition on the Error\nHandling Configuration File.<br/>\nWhat's been logged on this document, for each error, is:\n<p>Code Snippet 12. <b>Error Line structure logged on the error log file</b></p>\n<pre language=\"javascript\"><code>\ndate | error code | route | human readable explanation of the error | error details\n</code></pre>\n\n<h2>Mock Operation</h2>\nFor any endpoint that you define on your Routes Tree Configuration File, you have the chance to put it in mock operation\nstatus. By \"mock operation status\" we mean that whenever a user hits the endpoint a static, predefined, mock response will\nbe served. <br/>\nIn order to do that you need two things:\n<ul>\n<li>Configure the endpoint to serve only mock data</li>\n<li>Create a JSON file and put it in you mock files folder</li>\n</ul>\n\n<h3>How to set mock operation on</h3>\nThere are multiple ways to do that. First of all, in order to enable mock operations you have to set the mockData operation\non during the initialization of your application. We will see more details regarding the initial configuration object\npassed on application start later on, though for now just keep in mind that when we start our application we pass a configuration\nobject which on \"mockData\" key holds an object that defines the folder of your mock files and the flag that set mock operation\non or off.<br/>\nHaving our mock folder defined and set mock operation to on we can force an endpoint to serve mock data by:\n<ul>\n<li>Putting in our mock files folder a file with the name --endpoint-alias--.json, where \"--endpoint-alias--\" is the alias\nof the endpoint defined on the key \"alias\" of the endpoint on the Routes Tree Configuration File</li>\n<li>Setting the operation status of the endpoint to mock by setting the \"mock\" attribute of the endpoint on the Routes Tree\nConfiguration File to true</li>\n<li>Or by passing the parameter \"mock\" equals to 1 during the call</li>\n</ul>\nBy this way, whenever you hit the specific endpoint you'll always get back the mock data defined on the specified file on\nthe mock files folder.\n\n<h2>Controller Functions</h2>\nUp to now we've seen almost everything regarding the definition process of an endpoint, the params validation and the error\nhandling mechanisms but we've said nothing regarding the actual controller function.<br/>\nAssuming that a call passes all the middlewares, all the checks and it's not on mock operation status it reaches to the point\nwhere something actual needs to take place, a controller function should take care of the call.<br/>\nAll controller functions are defined in a single file. As stated in the beginning of this document, the actual aim of this\narchitectural decision is not, of course, to pack all the code within this file but more to have one single point where you\ncan assign responsibilities and define the controllers of all of your routes in a clean and readable way.<br/>\nThis single file is called Controller Functions File and it looks like this:\n\n<p>Code Snippet 12. <b>Example of Controller Functions File</b></p>\n<pre language=\"javascript\"><code>\nvar adminFunctions = require('./functions/admin.js');\nvar userFunctions = require('./functions/user.js');\n\nvar functions = {};\n\nfunctions['route-alias-1'] = adminFunctions.doSomething;\nfunctions['route-alias-2'] = userFunctions.doSomethingElse;\n\nexports.functions = functions;\n</code></pre>\nIt's just a mapping of all controller functions to the routes. As you can see from the example snippet 12, the Controller\nFunctions File should export an array. An associative array the keys of which are alias name of each route and the values\nthe corresponding controller functions of them. <br/>\nThe controller function for each endpoint is in the exact same format as a simple controller function that you would define\nif you used express without Express Happiness. That is:\n<p>Code Snippet 13. <b>Controller Function format</b></p>\n<pre language=\"javascript\"><code>\nvar my_controller_function = function(req, res, next){\n    // do your magic here\n}\n</code></pre>\nThe third argument (next) is optional though if you want to use the automatic error handling mechanism within these functions\n(that means to create a custom error, trigger it and let the Error Handling mechanism take care of it) you\ncertainly need the next function (see code snippet 10).\n\n<h2>Application Configuration on start</h2>\nHaving the full of your application configured it's now time to fire it up. Express Happiness starts with the command:\n<p>Code Snippet 15. <b>Starting your Express Happiness Server</b></p>\n<pre language=\"javascript\"><code>\nvar app = express();\nvar router = express.Router();\n\nvar eh = new expressHappiness(app, router, {\n    mockData:{\n        enable: true,\n        folder: '/path/to/mockdatafolder',\n        global: true\n    },\n    reusableFieldsFile: '/path/to/reusableFields.js',\n    errorFile: '/path/to/errors.log',\n    errorsConfigurationFile: '/path/to/conf/errors.js',\n    apiConfigurationFile: 'path/to/conf/restConf.js',\n    controllersFile: '/path/to/controllerFunctions.js'\n});\n\n\neh.generate('/v1',\n    {\n        'userAccess':[middlewareA, middlewareB],\n        'adminAccess':[middlewareC, middlewareD],\n        'eh-allRoutes':[middlewareX]\n    },\n    {\n        'userAccess':[middlewareA, middlewareB],\n        'adminAccess':[middlewareC, middlewareD],\n        'eh-allRoutes':[middlewareX]\n    }\n);\n</code></pre>\n\nFirst thing to do is to create a new Express Happiness instance. This is done by calling \"new expressHappiness\" function.\nThis function takes three parameters:\n<ul>\n<li><b>app</b>: the application initialized by the express() function invocation</li>\n<li><b>router</b>: The Router object provided by express which we can get through express.Router() invocation</li>\n<li><b>configuration</b>: a configuration object that sets the full Express Happiness environment up. Here we define the\npath of each file needed by EH and also the mock operation configuration.</li>\n</ul>\n\nAfter creating the EH instance we call the \"generate\" function of it. The \"generate\" function takes three parameters:\n<ul>\n<li><b>route path</b>: this is the base url that our application will support. For example if we are developing a REST\nAPI that listens to paths under /v1/ then we don't need to define this on the Routes Tree Configuration File. We can\ndefine it here by passing the '/v1' value on the first argument of the generate function</li>\n<li><b>pre-validation middlewares</b>: On the middlewares chain that are been executed on each call on our application,\nEH always includes a middleware that performs the params validation for the given endpoint. The second argument\nof the \"generate\" function provides us the ability to define a series of middlewares we want to get executed before reaching\nthe params validation step. The middlewares defined here, most often have to do with authentication issues. <br/>\nThe way we define our middlewares provides us the ability to explicitly define which middlewares should be executed according\nthe group that each route belongs to (see table 5). As mentioned, each endpoint might belong to one or more groups and this\nis defined by the \"groups\" attribute (which holds an array). So, in our example for all endpoints that belong to the 'userAccess' group\nthe middlewareA and middlewareB functions will be executed before the middlewares chain reaches the params validation step. For\nall middlewares that belong to the 'adminAccess' group the middlewareC and middlewareD will be executed before the params\nvalidation middleware gets execute and so on. <br/>\nIf we want to define pre-validation middlewares for all of our endpoints, no matter the groups they belong to, we can use\nthe \"eh-allRoutes\" key to define them. All middlewares included on this array are going to be executed, in the order they\nappear within the array, on all of our endpoints.\n</li>\n<li><b>post-validation middlewares</b>: The exact same things stand here. The third argument of the \"generate\" function\nexpects an object that though its keys defines the middlewares to be executed after the params validation process, on\nour routes, depending on the groups they belong to.\n</li>\n</ul>\n\nThe form of our middlewares should be the typical middleware form of express: function(req, res, next).\n\n<h2>Auto-generated API documentation</h2>\nAfter defining all of your endpoints with types and parameters on the root of your application there will be the documentation\nof your API. So, for example, if you run your app on localhost, port 7000, on http://localhost:7000 you'll find an\nauto-generated REST API documentation page.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "RESTcallsValidator.js",
    "content": "var erH, reusableRequiredFields;\nvar validator = require('validator');\nvar moment = require('moment');\nvar restConf = {};\n\nexports.assignConf = function(conf){\n    restConf = conf;\n}\n\nexports.init = function(confObj){\n    errorHandler = require('./ErrorHandler.js');\n    erH = new errorHandler(confObj.errorFile, confObj.errorsConfigurationFile);\n    reusableRequiredFields = require(confObj.reusableFieldsFile);\n}\n\nvar validateEmail = function(email){\n    var re = /^[a-zA-Z0-9+._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}$/;\n    return re.test(email);\n}\n\nvar hasTheErrorKey = function(field, errorKey){\n    if(field.validationFailureTexts != null && field.validationFailureTexts != undefined){\n        if(field.validationFailureTexts[errorKey] != null && field.validationFailureTexts[errorKey] != undefined){\n            return field.validationFailureTexts[errorKey]\n        }\n    }\n    return false;\n}\n\nvar unitValidator = {\n    int: function(field, value, path, errors, callback){\n        var fieldNameOnResponse = field.humanReadable || path.join('.');\n\n        if(!validator.isInt(value)){\n            var er_message = hasTheErrorKey(field, 'type');\n            if(er_message === false){\n                errors.push(fieldNameOnResponse + ' must be an integer. ' + value + ' provided.');\n            } else {\n                errors.push(er_message);\n            }\n        } else {\n            if(!!field.min){\n                if(value < field.min){\n                    var er_message = hasTheErrorKey(field, 'min');\n                    if(er_message === false){\n                        errors.push(fieldNameOnResponse + ' must be greater or equal to ' + field.min + '. ' + value + ' provided.');\n                    } else {\n                        errors.push(er_message);\n                    }\n                }\n            }\n            if(!!field.max){\n                if(value > field.min){\n                    var er_message = hasTheErrorKey(field, 'max');\n                    if(er_message === false) {\n                        errors.push(fieldNameOnResponse + ' must be lower or equal to ' + field.max + '. ' + value + ' provided.');\n                    } else {\n                        errors.push(er_message);\n                    }\n                }\n            }\n        }\n        callback();\n    },\n\n    date: function(field, value, path, errors, callback){\n        var fieldNameOnResponse = field.humanReadable || path.join('.');\n\n        var momentObj = moment(value, field.validationString);\n        if(!momentObj.isValid()){\n            var er_message = hasTheErrorKey(field, 'validationString');\n            if(er_message === false) {\n                errors.push(fieldNameOnResponse + ' must be a date in the format: ' + field.validationString + '. ' + value + ' provided.');\n            } else {\n                errors.push(er_message);\n            }\n        } else {\n            // in case of dates, for easiness we keep the momentObj representation of the passed variable, no matter\n            // which is the format of the date that we expect\n            //req.filteredParams[path.join('.') + field.key].momentObj = momentObj;\n        }\n        callback();\n    },\n\n    oneof: function(field, value, path, errors, callback){\n        var fieldNameOnResponse = field.humanReadable || path.join('.');\n\n        if(field.acceptedValues.indexOf(value) == -1){\n            var er_message = hasTheErrorKey(field, 'acceptedValues');\n            if(er_message === false) {\n                errors.push(fieldNameOnResponse + ' must be one of ' + field.acceptedValues.join(', ') + '. ' + value + ' provided.');\n            } else {\n                errors.push(er_message);\n            }\n        }\n        callback();\n    },\n\n    boolean: function(field, value, path, errors, callback){\n        var fieldNameOnResponse = field.humanReadable || path.join('.');\n\n        if(value !== true && value !== false && value !== 'true' && value !== 'false'){\n            var er_message = hasTheErrorKey(field, 'type');\n            if(er_message === false) {\n                errors.push(fieldNameOnResponse + ' must be a boolean. ' + value + ' provided.');\n            } else {\n                errors.push(er_message);\n            }\n        }\n        callback();\n    },\n\n    numeric: function(field, value, path, errors, callback){\n        var fieldNameOnResponse = field.humanReadable || path.join('.');\n\n        if(!validator.isFloat(value)){\n            var er_message = hasTheErrorKey(field, 'type');\n            if(er_message === false) {\n                errors.push(fieldNameOnResponse + ' must be a number. ' + value + ' provided.');\n            } else {\n                errors.push(er_message);\n            }\n        }\n        callback();\n    },\n\n    email: function(field, value, path, errors, callback){\n        var fieldNameOnResponse = field.humanReadable || path.join('.');\n\n        if(!validateEmail(value)){\n            var er_message = hasTheErrorKey(field, 'type');\n            if(er_message === false) {\n                errors.push(fieldNameOnResponse + ' must be a valid email address. ' + value + ' provided.');\n            } else {\n                errors.push(er_message);\n            }\n        }\n        callback();\n    },\n\n    string: function(field, value, path, errors, callback){\n        var fieldNameOnResponse = field.humanReadable || path.join('.');\n\n        if(!!field.minChars){\n            if(value.length < field.minChars){\n                var er_message = hasTheErrorKey(field, 'minChars');\n                if(er_message === false) {\n                    errors.push(fieldNameOnResponse + ' must be of at least ' + field.minChars + ' long. ' + value + ' provided.');\n                } else {\n                    errors.push(er_message);\n                }\n            }\n        }\n        if(!!field.maxChars){\n            if(value.length > field.maxChars){\n                var er_message = hasTheErrorKey(field, 'maxChars');\n                if(er_message === false) {\n                    errors.push(fieldNameOnResponse + ' must be of at max ' + field.maxChars + ' long. ' + value + ' provided.');\n                } else {\n                    errors.push(er_message);\n                }\n            }\n        }\n        if(!!field.regexp){\n            var er_message = hasTheErrorKey(field, 'type');\n            try{\n                var passes = field.regexp.test(value);\n                if(!passes){\n                    if(er_message === false) {\n                        errors.push(fieldNameOnResponse + ' do not match the provided regular expression');\n                    } else {\n                        errors.push(er_message);\n                    }\n                }\n            } catch(err){\n                if(er_message === false) {\n                    errors.push(fieldNameOnResponse + ' do not match the provided regular expression');\n                } else {\n                    errors.push(er_message);\n                }\n            }\n        }\n        callback();\n    },\n\n    array: function(field, value, path, errors){\n        var fieldNameOnResponse = field.humanReadable || path.join('.');\n\n        if(!(variable.constructor === Array)){\n            var er_message = hasTheErrorKey(field, 'type');\n            if(er_message === false) {\n                errors.push(fieldNameOnResponse + ' must be of type array. ' + value + ' provided.');\n            } else {\n                errors.push(er_message);\n            }\n        }\n        if(!!field.minLength){\n            if(value.length < field.minLength){\n                var er_message = hasTheErrorKey(field, 'minLength');\n                if(er_message === false) {\n                    errors.push(fieldNameOnResponse + ' must be of at least of ' + field.minLength + ' length. ' + value + ' provided.');\n                } else {\n                    errors.push(er_message);\n                }\n            }\n        }\n        if(!!field.maxLength){\n            if(value.length > field.maxLength){\n                var er_message = hasTheErrorKey(field, 'maxLength');\n                if(er_message === false) {\n                    errors.push(fieldNameOnResponse + ' must be of max length ' + field.maxLength + '. ' + value + ' provided.');\n                } else {\n                    errors.push(er_message);\n                }\n            }\n        }\n        callback();\n    }\n\n};\n\n\nvar firstLevelIterator = function(fields, errors, req, func, callback){\n    var index = 0;\n    var done = false;\n    var iterations = fields.length;\n    var loop = {\n        next: function(){\n            if(done){\n                return;\n            }\n\n            if(index < iterations){\n                var self = this;\n                var theField = fields[index];\n                unitValidate(theField, errors, req, [theField.key],\n                    function(){\n                        index++;\n                        func(self);\n                    }\n                );\n            } else {\n                done = true;\n                callback();\n            }\n        }\n    }\n\n    loop.next();\n    return loop;\n}\n\n\nvar validate = function(obj, errors, req, path, func, callback) {\n    var index = 0;\n    var done = false;\n    var iterations = Object.keys(obj.keys).length;\n    var objKeys = Object.keys(obj.keys);\n    var loop = {\n        next: function() {\n            if (done) {\n                return;\n            }\n\n            if (index < iterations) {\n                var newPath = path.slice();\n                newPath.push(objKeys[index]);\n                var self = this;\n                unitValidate(obj.keys[objKeys[index]], errors, req, newPath, function(){\n                    index++;\n                    func(self);\n                });\n\n            } else {\n                done = true;\n                callback();\n            }\n        }\n    };\n\n    loop.next();\n    return loop;\n};\n\n/*\n @unit: the unit to be validated taken from the signature\n @req: the request object\n @path: the base path of the current unit. It's an array\n @isRoot: a boolean indicating whether the passed unit is the root definition object or not\n @unitValidator: an instance of the unitValidator object defined above\n @callback: the callback to be called after the validation process\n */\nvar unitValidate = function(unit, errors, req, path, callback){\n    var get = req.expressHappiness.get;\n    var set = req.expressHappiness.set;\n\n    // step 1: check if the parameter is present if it's mandatory according to the signature\n    var mandatoryIssue = false;\n    if(path.length > 0){\n        if(unit.mandatory){\n            try{\n                var test_var = get(path[0]);\n                for(var i=1; i<path.length; i++){\n                    test_var = test_var[path[i]];\n                }\n                if(test_var === undefined || test_var === null){\n                    errors.push(path.join('.') + ' is mandatory. Though is missing');\n                    mandatoryIssue = true;\n                }\n            } catch(e){\n                errors.push(path.join('.') + ' is mandatory. Though is missing');\n                mandatoryIssue = true;\n            }\n        }\n    }\n\n    if(!mandatoryIssue){\n        if(unit.type === 'object'){\n            validate(unit, errors, req, path, function(loop){\n                loop.next();\n            }, callback)\n        } else {\n            try{\n                var value = get(path[0]);\n                for(var i=1; i<path.length; i++){\n                    value = value[path[i]];\n                }\n                if(value === undefined || value === null){\n                    callback();\n                } else {\n                    var validationFunct = unitValidator[unit.type];\n                    validationFunct(unit, value, path, errors, callback);\n                }\n            } catch(e){\n                callback();\n            }\n        }\n    } else {\n        callback();\n    }\n\n};\n\n\n\nexports.validateAttrs = function(req, res, next){\n    var get = req.expressHappiness.get;\n    var set = req.expressHappiness.set;\n\n    if(! restConf.routes[req.expressHappiness.apipath[0]] && !req.isRoot){\n        var err = new Error();\n        err.type = '404';\n        return next(err);\n    } else if(! restConf.routes[req.expressHappiness.apipath[0]] && req.isRoot){\n        return next();\n    } else {\n        var currentNode = restConf.routes[req.expressHappiness.apipath[0]];\n        for(var i=1; i<req.expressHappiness.apipath.length; i++){\n            currentNode = currentNode.subRoutes[req.expressHappiness.apipath[i]];\n            if(!currentNode){\n                var err = new Error();\n                err.type = '404';\n                return next(err);\n                break;\n            }\n        }\n\n        if(!currentNode[req.expressHappiness.apiMethod].fields){\n            return next();\n        }\n\n        var errors = [];\n\n        firstLevelIterator(currentNode[req.expressHappiness.apiMethod].fields, errors, req, function(loop){\n            loop.next();\n        }, function() {\n            if (errors.length > 0) {\n                var err = new Error();\n                err.type = 'invalidAttrs';\n                err.details = errors;\n                return next(err);\n            } else {\n                return next();\n            }\n        });\n    }\n}\n\nvar turnToFiltered = function(params){\n    var filtered = {};\n    for(k in params){\n        filtered[k] = {\n            value: params[k]\n        };\n    }\n    return filtered;\n}"
  },
  {
    "path": "conf/conf.js",
    "content": "var path = require('path');\n\nexports.conf = {\n    errorLogFile: path.resolve(__dirname, '../') + '/logs/error.log',\n    mockOperations:{\n        \"get:/kpis/traffic\":false,\n        \"get:/kpis/traffic/powerHours\": false,\n        \"get:/kpis/traffic/entrances\":false,\n        \"get:/kpis/dwellTime\":false,\n        \"get:/kpis/loyalty\":false,\n        \"get:/kpis/grossShoppingHours\":false,\n        \"get:/kpis/shoppersVsTravellers\":true,\n        \"get:/kpis/mallUse\":true,\n        \"get:/kpis/areaUse\":true,\n        \"get:/kpis/visitFrequency\":true,\n        \"get:/kpis/abandonmentRate\":false,\n        \"get:/kpis/drawRate\":false,\n        \"get:/kpis/opportunity\":false,\n        \"get:/kpis/hierarchy\": true,\n        \"get:/sites/:site_id/locations\": false\n    },\n    jwtSecret: 'N##$%W$&SFGHY$$^#W#%YLK\"HBH4l5hjhbkdsljly5%$elawkjgy3%Y4foijfAWT$QTJQALDGKSDJFY$%L^KJ%^'\n};\n"
  },
  {
    "path": "conf/errors.js",
    "content": "exports.errors = {\n    undefinedError:{\n        log:false,\n        humanReadable: 'Unresolved error code',\n        sendToClient: {\n            code:200,\n            data: 'ErrCode: 1 - There was an error fulfilling your request at the moment. Please try again in a while'\n        },\n        hooks:[\n            // here you can put whatever you want\n        ]\n    }\n}"
  },
  {
    "path": "conf/restConf.js",
    "content": "/*\nAll routes might belong to none, one or more groups.\nGrouping routes helps us apply middlewares targeting only specific sets of routes\nGrouping routes follows waterfall inheritance model. A group assigned to a route is been inherited by default by\n    all of its subroutes. For example:\n    routes:{\n        routeA:{\n            groups:['groupA'],\n            subRoutes:{\n                routeB:{\n                    // routeB by default belongs to 'groupA'\n                }\n            }\n        }\n    }\n    we can always change the groups that groupB (or any other sub-route) belongs to by redefining the groups attribute\n    for example if want routeB not to belong on groupA but to belong on groupB then we can do it by:\n    routes:{\n        routeA:{\n            groups:['groupA'],\n            subRoutes:{\n                routeB:{\n                    groups:['groupB']\n                }\n            }\n        }\n    }\n    and if want groupB to belong on groups at all then an empty groups attribute would do it:\n    routes:{\n        routeA:{\n            groups:[],\n            subRoutes:{\n                routeB:{\n                    // routeB by default belongs to 'groupA'\n                }\n            }\n        }\n    }\n */\n\n\nmodule.exports.conf = function(fieldsLoader){\n    return {\n        // API routes signatures\n        routes:{\n            kpis:{\n                groups:['userAccess'],\n                subRoutes:{\n                    traffic:\n                    {\n                        get:{\n                            description:'Get the traffic',\n                            fields:[\n                                fieldsLoader.getField('orgId'),\n                                fieldsLoader.getField('siteId'),\n                                fieldsLoader.getField('locationId'),\n                                fieldsLoader.getField('reportStartDate'),\n                                fieldsLoader.getField('reportEndDate'),\n                                fieldsLoader.getField('compareStartDate'),\n                                fieldsLoader.getField('compareEndDate'),\n                                fieldsLoader.getField('groupBy'),\n                                fieldsLoader.getField('countType'),\n                                fieldsLoader.getField('includeUnique'),\n                                fieldsLoader.getField('includeReturning')\n                            ]\n                        },\n                        subRoutes:{\n                            powerHours: {\n                                get:{\n                                    description:'Get the traffic power hours',\n                                    fields:[\n                                        fieldsLoader.getField('orgId'),\n                                        fieldsLoader.getField('siteId'),\n                                        fieldsLoader.getField('reportStartDate'),\n                                        fieldsLoader.getField('reportEndDate'),\n                                        fieldsLoader.getField('countType'),\n                                        fieldsLoader.getField('basePercentage')\n                                    ]\n                                }\n                            }\n                            ,entrances:{\n                                get:{\n                                    description:'Get the traffic monitoring point / quarter hour data',\n                                    fields:[\n                                        fieldsLoader.getField('orgId'),\n                                        fieldsLoader.getField('siteId'),\n                                        fieldsLoader.getField('reportStartDate'),\n                                        fieldsLoader.getField('reportEndDate'),\n                                        fieldsLoader.getField('countType'),\n                                        fieldsLoader.getField('groupBy', {mandatory:true})\n                                    ]\n                                }\n                            }\n                        }\n                    }\n                    ,\n                    dwellTime:{\n                        get:{\n                            description:'Get dwell time',\n                            fields:[\n                                fieldsLoader.getField('orgId'),\n                                fieldsLoader.getField('siteId'),\n                                fieldsLoader.getField('locationId'),\n                                fieldsLoader.getField('reportStartDate'),\n                                fieldsLoader.getField('reportEndDate'),\n                                fieldsLoader.getField('compareStartDate'),\n                                fieldsLoader.getField('compareEndDate'),\n                                fieldsLoader.getField('groupBy'),\n                                fieldsLoader.getField('includeDist'),\n                                {\n                                    key:'allLocations',\n                                    type:'boolean',\n                                    humanReadable: 'get massive report for all locations',\n                                    description:'Get data for all locations of a given site but for each location separately',\n                                    mandatory:false,\n                                    default:false\n                                }\n                            ]\n                        }\n                    },\n                    loyalty:{\n                        get:{\n                            description:'Get loyalty',\n                            fields:[\n                                fieldsLoader.getField('orgId'),\n                                fieldsLoader.getField('siteId'),\n                                fieldsLoader.getField('locationId'),\n                                fieldsLoader.getField('reportStartDate'),\n                                fieldsLoader.getField('reportEndDate'),\n                                fieldsLoader.getField('compareStartDate', {mandatory:true}),\n                                fieldsLoader.getField('compareEndDate', {mandatory:true}),\n                                fieldsLoader.getField('type')\n                            ]\n                        }\n                    },\n                    grossShoppingHours:{\n                        get:{\n                            description:'Get gross shopping hours',\n                            fields:[\n                                fieldsLoader.getField('orgId'),\n                                fieldsLoader.getField('siteId'),\n                                fieldsLoader.getField('locationId'),\n                                fieldsLoader.getField('reportStartDate'),\n                                fieldsLoader.getField('reportEndDate'),\n                                fieldsLoader.getField('compareStartDate'),\n                                fieldsLoader.getField('compareEndDate'),\n                                fieldsLoader.getField('groupBy'),\n                                fieldsLoader.getField('includeUnique'),\n                                fieldsLoader.getField('includeReturning')\n                            ]\n                        }\n                    },\n                    shoppersVsTravellers:{\n                        get:{\n                            description:'Get shoppers vs travellers',\n                            fields:[\n                                fieldsLoader.getField('orgId'),\n                                fieldsLoader.getField('reportStartDate'),\n                                fieldsLoader.getField('reportEndDate'),\n                                fieldsLoader.getField('compareStartDate'),\n                                fieldsLoader.getField('compareEndDate'),\n                                fieldsLoader.getField('groupBy')\n                            ]\n                        }\n                    },\n                    abandonmentRate:{\n                        get:{\n                            description:'Get abandonment rates',\n                            fields:[\n                                fieldsLoader.getField('orgId'),\n                                fieldsLoader.getField('siteId'),\n                                fieldsLoader.getField('locationId'),\n                                fieldsLoader.getField('reportStartDate'),\n                                fieldsLoader.getField('reportEndDate'),\n                                fieldsLoader.getField('compareStartDate'),\n                                fieldsLoader.getField('compareEndDate'),\n                                fieldsLoader.getField('groupBy')\n                            ]\n                        }\n                    },\n                    drawRate:{\n                        get:{\n                            description:'Get draw rate',\n                            fields:[\n                                fieldsLoader.getField('orgId'),\n                                fieldsLoader.getField('siteId'),\n                                fieldsLoader.getField('locationId'),\n                                fieldsLoader.getField('reportStartDate'),\n                                fieldsLoader.getField('reportEndDate'),\n                                fieldsLoader.getField('compareStartDate'),\n                                fieldsLoader.getField('compareEndDate'),\n                                fieldsLoader.getField('groupBy')\n                            ]\n                        }\n                    },\n                    opportunity:{\n                        get:{\n                            description:'Get opportunity',\n                            fields:[\n                                fieldsLoader.getField('orgId'),\n                                fieldsLoader.getField('siteId'),\n                                fieldsLoader.getField('locationId'),\n                                fieldsLoader.getField('reportStartDate'),\n                                fieldsLoader.getField('reportEndDate'),\n                                fieldsLoader.getField('compareStartDate'),\n                                fieldsLoader.getField('compareEndDate'),\n                                fieldsLoader.getField('groupBy')\n                            ]\n                        }\n                    }\n                }\n            },\n            auth: {\n                post: {\n                    description:'Authenticate user',\n                    fields:[\n                        fieldsLoader.getField('username'),\n                        fieldsLoader.getField('user_password')\n                    ]\n                }\n            },\n            users:{\n                groups:['superUserAccess'],\n                get:{\n                    description:'Get users',\n                    fields:[]\n                },\n                post:{\n                    description:'Post new user',\n                    fields:[\n                        fieldsLoader.getField('username'),\n                        fieldsLoader.getField('user_password')\n                    ]\n                },\n                subRoutes:{\n                    ':user_id':{\n                        get:{\n                            description:'Get a specific user info',\n                            fields:[]\n                        },\n                        put:{\n                            description: 'Edit user\\'s info',\n                            fields:[\n                                fieldsLoader.getField('user_password', {mandatory: false}),\n                                fieldsLoader.getField('expired'),\n                                fieldsLoader.getField('accessMap')\n                            ]\n                        },\n                        delete:{\n                            description: 'Delete user',\n                            fields:[]\n                        }\n                    }\n                }\n            },\n            organizations:{\n                groups:['userAccess'],\n                get:{\n                    groups:[],  // the endpoint will check access to filter down org list\n                    description:'Get organizations list',\n                    fields:[]\n                },\n                post:{\n                    groups:['superUserAccess'],\n                    description:'Create a new organization',\n                    fields:[\n                        fieldsLoader.getField('orgId'),\n                        fieldsLoader.getField('name')\n                    ]\n                },\n                subRoutes:{\n                    ':orgId':{\n                        get:{\n                            description: 'Organization\\'s details',\n                            fields:[]\n                        },\n                        put:{\n\n                            description:'Edit organization\\'s data',\n                            fields:[\n                                fieldsLoader.getField('name'),\n                                fieldsLoader.getField('expired')\n                            ]\n                        },\n                        delete:{\n\n                            description: 'Delete organization',\n                            fields:[]\n                        },\n                        subRoutes:{\n                            users:{\n                                groups:['orgAdmin'],\n                                get:{\n                                    description:'Get all users for which current user is an org admin',\n                                    fields:[]\n                                },\n                                post:{\n                                    description:'Add user to the current organization.  Create user if it does not exist.',\n                                    fields:[\n                                        fieldsLoader.getField('username'),\n                                        fieldsLoader.getField('user_password', {mandatory: false})\n                                    ]\n                                },\n                                subRoutes:{\n                                    ':user_id':{\n                                        get:{\n                                            description:'get the user data, including access map. if user does not exist OR is not in org, return not found',\n                                            fields:[]\n                                        },\n                                        put:{\n                                            description:'update user data, including access map. if user does not exist OR is not in org, return not found',\n                                            fields:[\n                                                fieldsLoader.getField('user_password', {mandatory: false}),\n                                                fieldsLoader.getField('expired'),\n                                                fieldsLoader.getField('accessMap')\n                                            ]\n                                        },\n                                        delete:{\n                                            description:'remove user from organization. Never removes the user completely',\n                                            fields:[]\n                                        }\n                                    }\n                                }\n                            },\n                            sites:{\n                                get:{\n                                    description:'Get sites list',\n                                    fields:[]\n                                },\n                                post:{\n\n                                    description:'Create a new site',\n                                    fields:[\n                                        fieldsLoader.getField('siteId'),\n                                        fieldsLoader.getField('name', {\n                                            description:'Site name',\n                                            humanReadable: 'Site name'\n                                        }),\n                                        fieldsLoader.getField('name', {\n                                            key:'organization_name'\n                                        }),\n                                        fieldsLoader.getField('geo')\n                                    ]\n                                },\n                                subRoutes:{\n                                    ':siteId':{\n                                        get:{\n                                            description: 'Site\\'s details',\n                                            fields:[]\n                                        },\n                                        put:{\n\n                                            description:'Edit site\\'s data',\n                                            fields:[\n                                                fieldsLoader.getField('name', {\n                                                    description:'Site name',\n                                                    humanReadable: 'Site name'\n                                                }),\n                                                fieldsLoader.getField('name', {\n                                                    key:'organization_name'\n                                                }),\n                                                fieldsLoader.getField('geo'),\n                                                fieldsLoader.getField('expired')\n                                            ]\n                                        },\n                                        delete:{\n\n                                            description: 'Delete site',\n                                            fields:[]\n                                        },\n                                        subRoutes:{\n                                            locations:{\n                                                get:{\n                                                    description: 'Get site\\'s locations',\n                                                    fields:[]\n                                                },\n                                                post:{\n\n                                                    description:'Create a new location',\n                                                    fields:[\n                                                        fieldsLoader.getField('location_id'),\n                                                        fieldsLoader.getField('location_type'),\n                                                        fieldsLoader.getField('name', {\n                                                            key:'site_name',\n                                                            description:'Site name',\n                                                            humanReadable: 'Site name'\n                                                        }),\n                                                        fieldsLoader.getField('name', {\n                                                            key:'organization_name',\n                                                            description:'Organization name',\n                                                            humanReadable: 'Organization name'\n                                                        }),\n                                                        fieldsLoader.getField('description'),\n                                                        fieldsLoader.getField('beacon_id'),\n                                                        fieldsLoader.getField('generic_other', {\n                                                            key:'nested_set_left'\n                                                        }),\n                                                        fieldsLoader.getField('generic_other', {\n                                                            key:'nested_set_right'\n                                                        }),\n                                                        fieldsLoader.getField('generic_other', {\n                                                            key:'nested_set_depth'\n                                                        }),\n                                                        fieldsLoader.getField('traffic_monitoring_point_entrance_id'),\n                                                        fieldsLoader.getField('traffic_monitoring_point_description')\n                                                    ]\n                                                },\n                                                subRoutes:{\n                                                    ':locationId':{\n                                                        get:{\n                                                            description: 'locations\\'s details',\n                                                            fields:[]\n                                                        },\n                                                        put:{\n\n                                                            description:'Edit locations\\'s data',\n                                                            fields:[\n                                                                fieldsLoader.getField('location_type'),\n                                                                fieldsLoader.getField('name', {\n                                                                    key:'site_name',\n                                                                    description:'Site name',\n                                                                    humanReadable: 'Site name'\n                                                                }),\n                                                                fieldsLoader.getField('name', {\n                                                                    key:'organization_name',\n                                                                    description:'Organization name',\n                                                                    humanReadable: 'Organization name'\n                                                                }),\n                                                                fieldsLoader.getField('description'),\n                                                                fieldsLoader.getField('beacon_id'),\n                                                                fieldsLoader.getField('generic_other', {\n                                                                    key:'nested_set_left'\n                                                                }),\n                                                                fieldsLoader.getField('generic_other', {\n                                                                    key:'nested_set_right'\n                                                                }),\n                                                                fieldsLoader.getField('generic_other', {\n                                                                    key:'nested_set_depth'\n                                                                }),\n                                                                fieldsLoader.getField('traffic_monitoring_point_entrance_id'),\n                                                                fieldsLoader.getField('traffic_monitoring_point_description'),\n                                                                fieldsLoader.getField('expired')\n                                                            ]\n                                                        },\n                                                        delete:{\n\n                                                            description: 'Delete locations',\n                                                            fields:[]\n                                                        }\n                                                    }\n                                                }\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n};"
  },
  {
    "path": "expressHappiness.js",
    "content": "var restConf = {\n    routes:[]\n}\nvar kpis\n    ,rcv;\nvar fs = require('fs');\nvar colors = require('colors');\nvar flatSignature = [];\nvar app, router, confObj;\n\n\nvar eh = function(p_app, p_router, conf){\n    app = p_app;\n    router = p_router;\n    var path = require('path');\n    var appDir = path.dirname(require.main.filename);\n    this.generate = successGenerate;\n\n    confObj = {\n        mockData:{\n            enable: true,\n            folder: appDir + '/mockJSONs',\n            global:false\n        },\n        reusableFieldsFile: appDir + '/expressHappiness/reusableFields.js',\n        errorFile:appDir + '/expressHappiness/errors.log',\n        errorsConfigurationFile:appDir + '/expressHappiness/conf/errors.js',\n        apiConfigurationFile:appDir + '/expressHappiness/conf/restConf.js',\n        controllersFile:appDir + '/expressHappiness/controllerFunctions.js'\n    };\n\n    if(!conf){\n        conf = {};\n    }\n    for(var propertyName in conf) {\n        if(conf.hasOwnProperty(propertyName)){\n            confObj[propertyName] = conf[propertyName];\n        }\n    }\n\n    var errorOccurred = false;\n    if(!fs.existsSync(confObj.reusableFieldsFile)){\n        errorOccurred = true;\n        var msg = \"Reusable fields file (\" + confObj.reusableFieldsFile + \") does not exist. Please create it according the documentation\";\n        console.log(msg.red.bgWhite);\n    }\n    if(!fs.existsSync(confObj.errorFile)){\n        errorOccurred = true;\n        var msg = \"Error log file (\" + confObj.errorFile + \") does not exist. Please create it according the documentation\";\n        console.log(msg.red.bgWhite);\n    }\n    if(!fs.existsSync(confObj.errorsConfigurationFile)){\n        errorOccurred = true;\n        var msg = \"Errors configuration file (\" + confObj.errorsConfigurationFile + \") does not exist. Please create it according the documentation\"\n        console.log(msg.red.bgWhite);\n    }\n    if(!fs.existsSync(confObj.apiConfigurationFile)){\n        errorOccurred = true;\n        var msg = \"REST API configuration file (\" + confObj.apiConfigurationFile + \") does not exist. Please create it according the documentation\"\n        console.log(msg.red.bgWhite);\n    }\n    if(!fs.existsSync(confObj.controllersFile)){\n        errorOccurred = true;\n        var msg = \"Controller functions definition file (\" + confObj.controllersFile + \") does not exist. Please create it according the documentation\"\n        console.log(msg.red.bgWhite);\n    }\n    if(confObj.mockData.enable && !fs.existsSync(confObj.mockData.folder)){\n        errorOccurred = true;\n        var msg = \"Mock data folder (\" + confObj.mockData.folder + \") does not exist. Please create it according the documentation\"\n        console.log(msg.red.bgWhite);\n    }\n\n    if(errorOccurred){\n        this.generate = failureGenerate;\n    } else {\n        // Rest validation initialization\n        var FL = require('./fieldsLoader.js');\n        var fieldsLoader = new FL(confObj.reusableFieldsFile);\n        restConf = require(confObj.apiConfigurationFile).conf(fieldsLoader);\n\n        global.expressHappiness = {\n            confObj: confObj\n        };\n        // TODO change the folder\n        rcv = require('./RESTcallsValidator.js');\n        rcv.init(confObj);\n        rcv.assignConf(restConf);\n        kpis = require(confObj.controllersFile);\n    }\n\n    this.start = function(port){\n        if(!port){\n            var msg = \"Please enter the port number for the app to run. Exiting.\";\n            console.log(msg.red.bgWhite);\n            process.exit(1);\n        } else {\n            isPortTaken(port, function(err, taken){\n                if(taken) {\n                    var msg = 'Port ' + port + ' is been used by another application. Exiting.';\n                    console.log(msg.red.bgWhite);\n                    process.exit(1);\n                } else {\n                    p_app.listen(port);\n                    var msg = 'The application is listening on port ' + port + ' for connections.';\n                    console.log(msg.green);\n                }\n            });\n        }\n    }\n\n}\n\n/*\nchecks if the port is taken\n */\nvar isPortTaken = function(port, fn) {\n    var net = require('net')\n    var tester = net.createServer()\n        .once('error', function (err) {\n            if (err.code != 'EADDRINUSE') return fn(err)\n            fn(null, true)\n        })\n        .once('listening', function() {\n            tester.once('close', function() { fn(null, false) })\n                .close()\n        })\n        .listen(port)\n}\n\n\n/* Reads the restConf and generates all available routes according to it.\n Also, it acts as debugger. For each of the generated routes the generate function checks if there is\n a corresponding method defined on the kpi controller, if there is mock data file available and it logs everything\n to the console.\n Missing methods are replaced by a generic one which handles their absence.\n Also, routes that do not provide mock data are configured so noMockAvailable function will be called whenever\n mock operation is on for them. For routes that actually have corresponding mock data files available the\n makeMockQuery function will be invoked for mock operation cases. Also, for efficiency reasons the makeMockQuery function\n for each of the routes that actually provide mock data is been generated once here (by reading the corresponding file)\n and it's been passed, so only one file read occurs for each route, only once, only at the kick off.\n It takes three parameters:\n @ router [object]: express framework router object\n @ baseUrl [string]: the base url of the routes to create\n @ preValidationMiddlewares [array][array]: holds all the middlewares that should be applied to the specific routes. These middlewares are been applied before validation\n it is an associative array. On restConf.js file each route might belong to one or more groups. For each group there might be different middlewares applied.\n This is achieved by using the group names as the first level keys of the array. Each key will hold another array which actual holds\n all the middlewares to be applied to the specific groups. Example:\n preValidationMiddlewares ~=\n [\n 'userAccess':[middlewareName1, middleware2],\n 'adminAccess':[middlewareName3, middleware4]\n ]\n if we want to apply a middleware to all of the routes, no matter what then we can define this by including it on the key \"eh-allRoutes\".\n Example:\n preValidationMiddlewares ~=\n [\n 'groupNameOne':[middlewareName1, middleware2],\n 'groupNameTwo':[middlewareName3, middleware4],\n 'eh-allRoutes':[middlewareToBeAppliedToAllRoutes1, middlewareToBeAppliedToAllRoutes2]\n ]\n @ postValidationMiddlewares [array][array]: holds all the middlewares that should be applied after the validation process and before the controller function invocation\n it is an associative array. On restConf.js file each route might belong to one or more groups. For each group there might be different middlewares applied.\n This is achieved by using the group names as the first level keys of the array. Each key will hold another array which actual holds\n all the middlewares to be applied to the specific groups. Example:\n postValidationMiddlewares ~=\n [\n 'groupNameOne':[middlewareName1, middleware2],\n 'groupNameTwo':[middlewareName3, middleware4]\n ]\n if we want to apply a middleware to all of the routes, no matter what then we can define this by including it on the key \"eh-allRoutes\".\n Example:\n postValidationMiddlewares ~=\n [\n 'groupNameOne':[middlewareName1, middleware2],\n 'groupNameTwo':[middlewareName3, middleware4],\n 'eh-allRoutes':[middlewareToBeAppliedToAllRoutes1, middlewareToBeAppliedToAllRoutes2]\n ]\n */\nvar successGenerate = function(baseUrl, preValidationMiddlewares, postValidationMiddlewares){\n    var theRoute = router.route(baseUrl + '/');\n    theRoute.get(putMethodsOnReq('get'));\n    theRoute.get(putApipathToReq([], ''));\n    theRoute.get(function(req, res, next){\n        req.isRoot = true;\n        return next();\n    });\n    for(var i=0; i<preValidationMiddlewares.length; i++){\n        theRoute.all(preValidationMiddlewares[i]);\n    }\n    theRoute.get(function(req, res){\n        var fs = require('fs');\n        fs.readFile(__dirname + '/views/index.html', { 'encoding':'utf8'}, function(err, data){\n            if(err){\n                console.log(err);\n            } else {\n                var _ = require('underscore');\n                var template = _.template(data);\n                res.send(template({signature:flatSignature}));\n            }\n        });\n        //res.render('null', {layout:'./index', signature:flatSignature});\n    });\n\n\n    var routeObject = {\n        subRoutes:  restConf.routes\n    };\n\n    generateNodeRoutes(routeObject, '', [], router, baseUrl, preValidationMiddlewares, postValidationMiddlewares, []);\n    registerErrors(app, confObj.errorsConfigurationFile, confObj.errorFile);\n};\n\nvar failureGenerate = function(){\n    console.log(\"Routes generation process skipped due to errors. Please fix the errors accordingly and retry\".red.bgWhite);\n    process.exit(0);\n}\n\nmodule.exports = eh;\n\nvar generateNodeRoutes = function(node, nodeName, path, router, baseUrl, preValidationMiddlewares, postValidationMiddlewares, inheritedGroups){\n    if(node.hasOwnProperty('groups')){\n        inheritedGroups = node.groups;\n    }\n    var supportedTypes = ['get', 'post', 'put', 'delete'];\n\n    for(var k=0; k<supportedTypes.length; k++){\n        if(node.hasOwnProperty(supportedTypes[k])){\n            if(node[supportedTypes[k]].hasOwnProperty('groups')){\n                inheritedGroups = node[supportedTypes[k]].groups;\n            }\n            flatSignature.push({\n                type: supportedTypes[k],\n                node:node[supportedTypes[k]],\n                path:baseUrl + path.join('/') + '/' + nodeName\n            });\n\n            var mockQueryMiddleware = mockQueryGenerationMiddleWare(supportedTypes[k], path, nodeName, node[supportedTypes[k]].alias);\n\n            var theRoute = router.route(baseUrl + path.join('/') + '/' + nodeName);\n            theRoute[supportedTypes[k]](putMethodsOnReq(supportedTypes[k]));\n            theRoute[supportedTypes[k]](putApipathToReq(path, nodeName,\n                node[supportedTypes[k]].alias, node[supportedTypes[k]].mock));\n\n            if(preValidationMiddlewares.hasOwnProperty('eh-allRoutes')){\n                for(var ii=0; ii<preValidationMiddlewares['eh-allRoutes'].length; ii++){\n                    theRoute[supportedTypes[k]](preValidationMiddlewares['eh-allRoutes'][ii]);\n                }\n            }\n            for(var i=0; i<inheritedGroups.length; i++){\n                if(preValidationMiddlewares.hasOwnProperty(inheritedGroups[i])){\n                    for(var ii=0; ii<preValidationMiddlewares[inheritedGroups[i]].length; ii++){\n                        theRoute[supportedTypes[k]](preValidationMiddlewares[inheritedGroups[i]][ii]);\n                    }\n                }\n            }\n\n            theRoute[supportedTypes[k]](rcv.validateAttrs);\n            theRoute[supportedTypes[k]](mockQueryMiddleware);\n            theRoute[supportedTypes[k]](mockMiddlewareApplied);\n\n            if(postValidationMiddlewares){\n                if(postValidationMiddlewares.hasOwnProperty('eh-allRoutes')){\n                    for(var ii=0; ii<postValidationMiddlewares['eh-allRoutes'].length; ii++){\n                        theRoute[supportedTypes[k]](postValidationMiddlewares['eh-allRoutes'][ii]);\n                    }\n                }\n                for(var i=0; i<inheritedGroups.length; i++){\n                    if(postValidationMiddlewares.hasOwnProperty(inheritedGroups[i])){\n                        for(var ii=0; ii<postValidationMiddlewares[inheritedGroups[i]].length; ii++){\n                            theRoute[supportedTypes[k]](postValidationMiddlewares[inheritedGroups[i]][ii]);\n                        }\n                    }\n                }\n            }\n\n            var aliasedFunction = false;\n            if(node[supportedTypes[k]].alias){\n                if(kpis.functions[node[supportedTypes[k]].alias] != undefined && kpis.functions[node[supportedTypes[k]].alias] != null){\n                    theRoute[supportedTypes[k]](kpis.functions[node[supportedTypes[k]].alias]);\n                    aliasedFunction = true;\n                }\n            }\n\n            if(!aliasedFunction){\n                if(kpis.functions[supportedTypes[k] + \":\" + path.join('/') + '/' + nodeName] != undefined && kpis.functions[supportedTypes[k] + \":\" + path.join('/') + '/' + nodeName] != null){\n                    theRoute[supportedTypes[k]](kpis.functions[supportedTypes[k] + \":\" + path.join('/') + '/' + nodeName]);\n                } else {\n                    var msg = '-- WARNING -- There is currently no control method defined for route ' + path.join('/') + '/' + nodeName + '. Please create it on /controllers/routesControllerFunctions.js and assign it to functions[\"' + path.join('/') + '/' + nodeName + '\"]';\n                    console.log(msg.red.bgWhite);\n                    theRoute[supportedTypes[k]](noControlMethodCallback);\n                }\n            }\n\n\n            console.log('Route ' + supportedTypes[k].toUpperCase() + ' \"'  + path.join('/') + '/' + nodeName + '\" created successfully'.green);\n        }\n    }\n\n    if(node.hasOwnProperty('subRoutes')){\n        var newPath = path.slice(0);\n        newPath.push(nodeName);\n        for(var property in node.subRoutes) {\n            if(node.subRoutes.hasOwnProperty(property)){ // first we check that the property is not an inherited one\n                generateNodeRoutes(node.subRoutes[property], property, newPath, router, baseUrl, preValidationMiddlewares, postValidationMiddlewares, inheritedGroups);\n            }\n        }\n    }\n\n    app.use('', router);\n    app.get('*', function(req, res, next){\n        var err = new Error();\n        err.type = '404';\n        return next(err);\n    });\n}\n\n\nvar putMethodsOnReq = function(method){\n    return function(req, res, next){\n        req.expressHappiness = {};\n        req.expressHappiness.apiMethod = method;\n        req.expressHappiness.get = getGetter(req);\n        req.expressHappiness.set = getSetter(req);\n        return next();\n    }\n}\n\n\nvar mockQueryGenerationMiddleWare = function(type, path, nodeName, alias){\n    if(!global.expressHappiness.confObj.mockData.enable){\n        return function(req, res, next){\n            return next();\n        }\n    }\n\n    var filename = '';\n    var route = '';\n    for(var i=1; i<path.length; i++){\n        filename += path[i] + '.';\n        route += path[i] + '/';\n    }\n    route += nodeName;\n    filename += nodeName;\n\n    if(alias){\n        if(fs.existsSync(global.expressHappiness.confObj.mockData.folder + '/' + alias + '.json')){\n            var mockData = require(global.expressHappiness.confObj.mockData.folder + '/' + alias + '.json');\n\n            return function(req, res, next){\n                req.expressHappiness.mockQuery = function(success){\n                    success(mockData);\n                }\n                return next();\n            }\n        }\n    }\n\n\n    if(fs.existsSync(global.expressHappiness.confObj.mockData.folder + '/' + type + '.' + filename + '.json')){\n        var mockData = require(global.expressHappiness.confObj.mockData.folder + '/' + type + '.' + filename + '.json');\n\n        return function(req, res, next){\n            req.expressHappiness.mockQuery = function(success){\n                success(mockData);\n            }\n            return next();\n        }\n    } else {\n        var msg = '-- WARNING -- No mock data found for ' + route + ' route. Please create file named ' + filename + '.json and place it on mockJSONs folder';\n        console.log(msg.red.bgWhite);\n        return function(req, res, next){\n            req.expressHappiness.mockQuery = function(success){\n                var err = new Error();\n                err.type = 'noMockData';\n                return next(err);\n            };\n            return next();\n        }\n    }\n}\n\nvar getGetter = function(req){\n    if(req.expressHappiness.apiMethod == 'get'){\n        return function(key){\n            return req.query[key];;\n        }\n    } else {\n        return function (key) {\n            return req.body[key];\n        }\n    }\n}\n\nvar getSetter = function(req){\n    if(req.expressHappiness.apiMethod == 'get'){\n        return function(key, value){\n            req.query[key] = value;\n        }\n    } else {\n        return function(key, value){\n            req.body[key] = value;\n        }\n    }\n}\n\n\nvar noControlMethodCallback = function(req, res, next){\n    var err = new Error(\"Under Development\");\n    err.type = 'underDevelopment';\n    return next(err);\n}\n\nvar putApipathToReq = function(path, nodeName, alias, mock){\n    return function(req, res, next){\n        var newPath = path.slice(0);\n        newPath.shift();\n        newPath.push(nodeName);\n        req.expressHappiness.apipath = newPath;\n        req.expressHappiness.routeAlias = alias;\n        req.expressHappiness.mock = mock;\n        return next();\n    }\n}\n\n\nvar mockMiddlewareApplied = function(req, res, next){\n    if(global.expressHappiness.confObj.mockData.global){\n        req.expressHappiness.mockQuery(function(results){\n            return res.send(results);\n        });\n    } else if((req.expressHappiness.get('mock') != 1 && !req.expressHappiness.mock) || !global.expressHappiness.confObj.mockData.enable){\n        return next();\n    } else {\n        req.expressHappiness.mockQuery(function(results){\n            return res.send(results);\n        });\n    }\n}\n\nvar registerErrors = function(app, errorsConfigurationFile, errorFile){\n    var errors = require(errorsConfigurationFile).errors;\n    var undefinedError = {\n        log:true,\n        humanReadable: 'Unresolved error code',\n        sendToClient: {\n            code:500\n        }\n    };\n\n    var invalidAttrs = {\n        log:true,\n        humanReadable: 'Invalid attributes passed',\n        sendToClient: {\n            code:400,\n            data:'err.details'\n        }\n    };\n\n    var fourZeroFour = {\n        log:false,\n        humanReadable: 'The requested resource does not exist',\n        sendToClient: {\n            code:404\n        }\n    };\n\n    var noMockData = {\n        log: true,\n        humanReadable: 'There is no mock data available for this route yet',\n        sendToClient: {\n            code: 404,\n            data:'There is no mock data available for this route yet'\n        }\n    };\n\n    var underDevelopment = {\n        log: false,\n        humanReadable: 'A call to a route under development has been made',\n        sendToClient:{\n            code:501,\n            data:'This route is currently under development'\n        }\n    };\n\n    if(!errors.hasOwnProperty('undefinedError')) {\n        errors.undefinedError = undefinedError;\n    } else {\n        errors.undefinedError = formatError(undefinedError, errors.undefinedError)\n    }\n    if(!errors.hasOwnProperty('invalidAttrs')) {\n        errors.invalidAttrs = invalidAttrs;\n    } else {\n        errors.invalidAttrs = formatError(invalidAttrs, errors.invalidAttrs)\n    }\n    if(!errors.hasOwnProperty('404')) {\n        errors['404'] = fourZeroFour;\n    } else {\n        errors['404'] = formatError(fourZeroFour, errors['404'])\n    }\n    if(!errors.hasOwnProperty('noMockData')) {\n        errors.noMockData = noMockData;\n    } else {\n        errors.noMockData = formatError(noMockData, errors.noMockData)\n    }\n    if(!errors.hasOwnProperty('underDevelopment')) {\n        errors.underDevelopment = underDevelopment;\n    } else {\n        errors.underDevelopment = formatError(underDevelopment, errors.underDevelopment)\n    }\n\n    var ErrorHandlerModule = require('./ErrorHandler.js');\n    var ErrorHanlder = new ErrorHandlerModule(errorFile);\n    app.use(function (err, req, res, next) {\n        if(errors.hasOwnProperty(err.type)){\n            ErrorHanlder.handleError(errors[err.type], err, req, res);\n        } else {\n            ErrorHanlder.handleError(errors.undefinedError, err, req, res);\n        }\n    });\n};\n\nvar formatError = function(error, options){\n    var keys = Object.keys(options);\n    for(var i=0; i<keys.length; i++){\n        var key = keys[i];\n        error[key] = options[key];\n    }\n    return error;\n}"
  },
  {
    "path": "fieldsLoader.js",
    "content": "module.exports = function(reusableFile){\n    var reusableRequiredFields = require(reusableFile);\n\n    /*\n     Returns the corresponding field object from the reusableRequiredFields variable\n\n     @name: the name of the field\n     @options: optionally pass an options object. All keys of this object will be used to overwrite the default values\n     of the the corresponding keys of the original field definition.\n\n     Example:\n     getField('orgId')\n     Returns:\n     {\n     key:'orgId',\n     type:'int',\n     humanReadable: 'organization id',\n     description:'The Organization from which data is requested',\n     mandatory:true\n     }\n\n     getField('orgId', {mandatory:false});\n     Returns:\n     {\n     key:'orgId',\n     type:'int',\n     humanReadable: 'organization id',\n     description:'The Organization from which data is requested',\n     mandatory:false\n     }\n     */\n    this.getField = function(name, options){\n        if(!reusableRequiredFields[name]){\n            console.log('The requested field ' + name + ' does not exist on the reusableRequiredFields object');\n            return {\n                key:'invalid_key'\n            };\n        } else {\n            var toReturn = JSON.parse(JSON.stringify(reusableRequiredFields[name]));\n            if(!!options){\n                var keys = Object.keys(options);\n                for(var i=0; i<keys.length; i++){\n                    var key = keys[i];\n                    toReturn[key] = options[key];\n                }\n            }\n            return toReturn;\n        }\n    }\n}"
  },
  {
    "path": "helpers/helpers.js",
    "content": "var validate = function(obj, func, callback) {\n    var index = 0;\n    var done = false;\n    var iterations = Object.keys(obj).length;\n    var objKeys = Object.keys(obj);\n    console.log('got into validate');\n    console.log('Number of keys: ' + iterations);\n    var loop = {\n        next: function() {\n            if (done) {\n                return;\n            }\n\n            if (index < iterations) {\n                var self = this;\n                unitValidate(obj[objKeys[index]], function(){\n                    index++;\n                    func(self);\n                });\n\n            } else {\n                done = true;\n                callback();\n            }\n        }\n    };\n\n    loop.next();\n    return loop;\n};\n\n\nvar unitValidate = function(unit, callback){\n    console.log('unit: ');\n    console.log(unit);\n    if(typeof unit === 'object'){\n        console.log('unit is object')\n        validate(unit, function(loop){\n            loop.next();\n        }, callback)\n    } else {\n        console.log('unit is primitive');\n        console.log('validating unit');\n        callback();\n    }\n};\n\nvar obj = {\n    a:4,\n    b:'test',\n    c:{\n        ca:'ca',\n        cb:4,\n        d:{\n            da:'abc',\n            db:1412\n        }\n    }\n}\n\nunitValidate(obj, function() {\n        console.log('done');\n    }\n);"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"express-happiness\",\n  \"version\": \"0.7.2\",\n  \"description\": \"Express framework wrapper\",\n  \"main\": \"expressHappiness.js\",\n  \"dependencies\" : {\n    \"validator\" : \"^3.34.0\"\n  , \"colors\" : \"^1.0.3\"\n  , \"moment\" : \"^2.9.0\"\n  , \"underscore\":\"^1.8.2\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/andreas-trad/express-happiness.git\"\n  },\n  \"keywords\": [\n    \"express\"\n  ],\n  \"author\": \"Andreas Trantidis <atrantidis@gmail.com>\",\n  \"license\": \"BSD-2-Clause\",\n  \"bugs\": {\n    \"url\": \"https://github.com/andreas-trad/express-happiness/issues\"\n  }\n}"
  },
  {
    "path": "views/index.html",
    "content": "\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <title>KPIS documentation</title>\n\n    <!-- Bootstrap core CSS -->\n    <link href=\"//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css\" rel=\"stylesheet\">\n\n</head>\n\n<body role=\"document\">\n<div class=\"container theme-showcase\" role=\"main\">\n\n    <% _.each(signature, function(item){ %>\n    <div class=\"page-header\">\n        <h1><%= item.type.toUpperCase() %> <%= item.path %></h1>\n    </div>\n\n    <div class=\"well\">\n        <p><%= item.node.description %></p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <h2>Parameters</h2>\n            <table class=\"table table-striped\">\n                <thead>\n                <tr>\n                    <th>Name</th>\n                    <th>Type</th>\n                    <th>Description</th>\n                    <th>Mandatory</th>\n                    <th>Extra Info</th>\n                </tr>\n                </thead>\n                <tbody>\n                <% _.each(item.node.fields, function(field){ %>\n                <tr>\n                    <td><%= field.key %></td>\n                    <td><%= field.type %></td>\n                    <td><%= field.description %></td>\n                    <td><% if(field.mandatory){ %>Yes<% } else { %>No<% } %></td>\n                    <td>\n                        <% if(field.type == 'oneof'){ %>Must be one of: <%= field.acceptedValues.join(', ') %><% } %>\n                        <% if(field.type == 'date'){ %>Accepted date format: <%= field.validationString %><% } %>\n                        <% if(field.type == 'string' && !!field.minChars){ %>Must be at least <%= field.minChars %> characters long <% } %>\n                        <% if(field.type == 'string' && !!field.maxChars){ %>Must be at max <%= field.maxChars %> characters long <% } %>\n                    </td>\n                </tr>\n                <% }); %>\n                </tbody>\n            </table>\n        </div>\n    </div>\n    <% }); %>\n\n</div> <!-- /container -->\n\n\n<!-- Bootstrap core JavaScript\n================================================== -->\n<!-- Placed at the end of the document so the pages load faster -->\n<script src=\"/js/jquery.min.js\"></script>\n<script src=\"/js/bootstrap.min.js\"></script>\n</body>\n</html>\n"
  }
]