gina 0.1.1-alpha.17 → 0.1.1-alpha.171

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (356) hide show
  1. package/AUTHORS +2 -1
  2. package/LICENSE +1 -1
  3. package/README-4Contributors.md +30 -0
  4. package/README.md +202 -32
  5. package/bin/cli +165 -68
  6. package/bin/cli-debug +49 -18
  7. package/bin/cmd +40 -18
  8. package/bin/gina +48 -37
  9. package/{framework/v0.1.1-alpha.17/core/template/command/gina.bat.tpl → bin/gina.bat} +0 -0
  10. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/AUTHORS +0 -0
  11. package/framework/{v0.1.1-alpha.17/lib/inherits → v0.1.1-alpha.171}/LICENSE +1 -1
  12. package/framework/v0.1.1-alpha.171/VERSION +1 -0
  13. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/asset/html/nolayout.html +0 -0
  14. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/asset/html/static.html +0 -0
  15. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/asset/img/android-chrome-192x192.png +0 -0
  16. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/asset/img/android-chrome-512x512.png +0 -0
  17. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/asset/img/apple-touch-icon.png +0 -0
  18. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/asset/img/favicon-16x16.png +0 -0
  19. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/asset/img/favicon-32x32.png +0 -0
  20. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/asset/img/favicon.ico +0 -0
  21. package/framework/{v0.1.1-alpha.17/core/asset/js/plugin/readme.md → v0.1.1-alpha.171/core/asset/plugin/README.md} +31 -9
  22. package/framework/v0.1.1-alpha.171/core/asset/plugin/dist/vendor/gina/css/gina.min.css +1 -0
  23. package/framework/v0.1.1-alpha.171/core/asset/plugin/dist/vendor/gina/css/gina.min.css.map +1 -0
  24. package/framework/v0.1.1-alpha.171/core/asset/plugin/dist/vendor/gina/html/toolbar.html +251 -0
  25. package/framework/{v0.1.1-alpha.17/core/asset/js/plugin/dist → v0.1.1-alpha.171/core/asset/plugin/dist/vendor/gina/js}/gina.js +3786 -3007
  26. package/framework/v0.1.1-alpha.171/core/asset/plugin/dist/vendor/gina/js/gina.min.js +756 -0
  27. package/framework/v0.1.1-alpha.171/core/asset/plugin/dist/vendor/gina/js/gina.min.js.map +8 -0
  28. package/framework/v0.1.1-alpha.171/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js +5 -0
  29. package/framework/v0.1.1-alpha.171/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.map +8 -0
  30. package/framework/{v0.1.1-alpha.17/core/asset/js → v0.1.1-alpha.171/core/asset}/plugin/uuid.json +0 -0
  31. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/config.js +95 -39
  32. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/connectors/couchbase/index.js +332 -223
  33. package/framework/v0.1.1-alpha.171/core/connectors/couchbase/lib/connector.js +22 -0
  34. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/connectors/couchbase/lib/connector.v2.js +51 -51
  35. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/connectors/couchbase/lib/connector.v3.js +51 -51
  36. package/framework/v0.1.1-alpha.171/core/connectors/couchbase/lib/connector.v4.js +384 -0
  37. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/connectors/couchbase/lib/n1ql.js +3 -2
  38. package/framework/v0.1.1-alpha.171/core/connectors/couchbase/lib/session-store.js +22 -0
  39. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/connectors/couchbase/lib/session-store.v2.js +0 -0
  40. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/connectors/couchbase/lib/session-store.v3.js +12 -12
  41. package/framework/v0.1.1-alpha.171/core/connectors/couchbase/lib/session-store.v4.js +361 -0
  42. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/controller/controller.framework.js +0 -0
  43. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/controller/controller.js +787 -743
  44. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/controller/index.js +0 -0
  45. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/deps/busboy/.travis.yml +0 -0
  46. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/deps/busboy/LICENSE +0 -0
  47. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/deps/busboy/README.md +0 -0
  48. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/deps/busboy/deps/encoding/encoding-indexes.js +0 -0
  49. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/deps/busboy/deps/encoding/encoding.js +0 -0
  50. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/deps/busboy/lib/main.js +0 -0
  51. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/deps/busboy/lib/types/multipart.js +0 -0
  52. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/deps/busboy/lib/types/urlencoded.js +0 -0
  53. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/deps/busboy/lib/utils.js +0 -0
  54. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/deps/busboy/package.json +0 -0
  55. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/deps/swig-client/swig-2.0.0.min.js +0 -0
  56. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/dev/index.js +1 -1
  57. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/dev/lib/class.js +1 -1
  58. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/dev/lib/factory.js +2 -2
  59. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/dev/lib/tools.js +0 -0
  60. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/gna.js +13 -9
  61. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/locales/README.md +5 -0
  62. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/locales/currency.json +0 -0
  63. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/locales/dist/language/en.json +0 -0
  64. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/locales/dist/language/fr.json +0 -0
  65. package/framework/v0.1.1-alpha.171/core/locales/dist/region/en.json +5727 -0
  66. package/framework/v0.1.1-alpha.171/core/locales/dist/region/fr.json +11452 -0
  67. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/locales/index.js +2 -2
  68. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/locales/src/make.js +39 -41
  69. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/locales/src/resources/currency.csv +0 -0
  70. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/locales/src/resources/region.csv +0 -0
  71. package/framework/v0.1.1-alpha.171/core/locales/src/resources/region.mapping.json +43 -0
  72. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/mime.types +0 -0
  73. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/model/entity.js +87 -67
  74. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/model/index.js +16 -16
  75. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/model/template/entityFactory.js +1 -1
  76. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/model/template/index.js +15 -14
  77. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/README.md +0 -0
  78. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/index.js +1 -1
  79. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/lib/file/README.md +0 -0
  80. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/lib/file/build.json +0 -0
  81. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/lib/file/package.json +1 -1
  82. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/lib/intl/README.md +0 -0
  83. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/lib/intl/build.json +0 -0
  84. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/lib/intl/package.json +1 -1
  85. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/lib/intl/src/main.js +5 -5
  86. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/lib/storage/README.md +0 -0
  87. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/lib/storage/build.json +0 -0
  88. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/lib/storage/package.json +1 -1
  89. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/lib/storage/src/main.js +4 -4
  90. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/lib/validator/README.md +0 -0
  91. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/lib/validator/build.json +0 -0
  92. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/lib/validator/package.json +1 -1
  93. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/lib/validator/src/form-validator.js +397 -296
  94. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/plugins/lib/validator/src/main.js +1279 -1256
  95. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/router.js +95 -79
  96. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/server.express.js +0 -0
  97. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/server.isaac.js +118 -109
  98. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/server.js +230 -57
  99. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/status.codes +0 -0
  100. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/boilerplate/bundle/config/app.json +0 -0
  101. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/boilerplate/bundle/config/routing.json +0 -0
  102. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/boilerplate/bundle/config/settings.json +0 -0
  103. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/boilerplate/bundle/config/settings.server.json +4 -4
  104. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/boilerplate/bundle/config/templates.json +4 -4
  105. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/boilerplate/bundle/controllers/controller.content.js +1 -1
  106. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/boilerplate/bundle/controllers/controller.js +0 -0
  107. package/framework/v0.1.1-alpha.171/core/template/boilerplate/bundle/controllers/setup.js +111 -0
  108. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/boilerplate/bundle/index.js +13 -1
  109. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/boilerplate/bundle_namespace/controllers/controller.js +0 -0
  110. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/boilerplate/bundle_public/css/default.css +0 -0
  111. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/boilerplate/bundle_public/css/vendor/readme.md +0 -0
  112. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/boilerplate/bundle_public/favicon.ico +0 -0
  113. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/boilerplate/bundle_public/js/vendor/readme.md +0 -0
  114. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/boilerplate/bundle_public/readme.md +0 -0
  115. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/boilerplate/bundle_templates/handlers/main.js +0 -0
  116. package/framework/v0.1.1-alpha.171/core/template/boilerplate/bundle_templates/html/content/homepage.html +8 -0
  117. package/framework/v0.1.1-alpha.171/core/template/boilerplate/bundle_templates/html/includes/error-msg-noscript.html +11 -0
  118. package/framework/v0.1.1-alpha.171/core/template/boilerplate/bundle_templates/html/includes/error-msg-outdated-browser.html +8 -0
  119. package/framework/{v0.1.1-alpha.17/core/template/boilerplate/bundle_templates/html/layout → v0.1.1-alpha.171/core/template/boilerplate/bundle_templates/html/layouts}/main.html +10 -3
  120. package/framework/v0.1.1-alpha.171/core/template/command/gina.bat.tpl +8 -0
  121. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/command/gina.tpl +4 -4
  122. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/conf/env.json +11 -0
  123. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/conf/manifest.json +0 -0
  124. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/conf/package.json +1 -1
  125. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/conf/settings.json +0 -0
  126. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/conf/statics.json +3 -3
  127. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/conf/templates.json +2 -2
  128. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/error/client/json/401.json +0 -0
  129. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/error/client/json/403.json +0 -0
  130. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/error/client/json/404.json +0 -0
  131. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/error/server/html/50x.html +0 -0
  132. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/error/server/json/500.json +0 -0
  133. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/error/server/json/503.json +0 -0
  134. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/core/template/extensions/logger/config.json +0 -0
  135. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/helpers/console.js +3 -3
  136. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/helpers/context.js +146 -6
  137. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/helpers/dateFormat.js +9 -7
  138. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/helpers/index.js +13 -8
  139. package/framework/v0.1.1-alpha.171/helpers/json/LICENSE +9 -0
  140. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/helpers/json/README.md +0 -0
  141. package/framework/{v0.1.1-alpha.17/helpers/plugins → v0.1.1-alpha.171/helpers/json}/package.json +2 -2
  142. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/helpers/json/src/main.js +25 -25
  143. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/helpers/path.js +163 -96
  144. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/helpers/plugins/README.md +0 -0
  145. package/framework/{v0.1.1-alpha.17/helpers/json → v0.1.1-alpha.171/helpers/plugins}/package.json +2 -2
  146. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/helpers/plugins/src/api-error.js +23 -23
  147. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/helpers/plugins/src/main.js +3 -3
  148. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/helpers/prototypes.js +46 -38
  149. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/helpers/task.js +21 -14
  150. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/helpers/text.js +2 -2
  151. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/archiver/README.md +0 -0
  152. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/archiver/build.json +0 -0
  153. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/archiver/package.json +1 -1
  154. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/archiver/src/dep/jszip.min.js +3 -3
  155. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/archiver/src/main.js +168 -168
  156. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/aliases.json +4 -1
  157. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/bundle/add.js +43 -17
  158. package/framework/v0.1.1-alpha.171/lib/cmd/bundle/arguments.json +6 -0
  159. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/bundle/copy.js +0 -0
  160. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/bundle/cp.js +0 -0
  161. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/bundle/help.js +0 -0
  162. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/bundle/help.txt +2 -2
  163. package/framework/v0.1.1-alpha.171/lib/cmd/bundle/list.js +176 -0
  164. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/bundle/remove.js +22 -22
  165. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/bundle/rename.js +0 -0
  166. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/bundle/restart.js +0 -0
  167. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/bundle/rm.js +0 -0
  168. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/bundle/start.js +264 -46
  169. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/bundle/status.js +0 -0
  170. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/bundle/stop.js +93 -74
  171. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/env/add.js +0 -0
  172. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/env/get.js +0 -0
  173. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/env/help.js +0 -0
  174. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/env/help.txt +0 -0
  175. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/env/link-dev.js +0 -0
  176. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/env/list.js +20 -4
  177. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/env/remove.js +0 -0
  178. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/env/rm.js +0 -0
  179. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/env/set.js +0 -0
  180. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/env/unset.js +0 -0
  181. package/framework/{v0.1.1-alpha.17/lib/cmd/scope → v0.1.1-alpha.171/lib/cmd/env}/use.js +21 -1
  182. package/framework/v0.1.1-alpha.171/lib/cmd/framework/build.js +85 -0
  183. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/framework/dot.js +0 -0
  184. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/framework/get.js +0 -0
  185. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/framework/help.js +0 -0
  186. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/framework/help.txt +0 -0
  187. package/framework/v0.1.1-alpha.171/lib/cmd/framework/init.js +798 -0
  188. package/framework/v0.1.1-alpha.171/lib/cmd/framework/link-node-modules.js +86 -0
  189. package/framework/v0.1.1-alpha.171/lib/cmd/framework/link.js +110 -0
  190. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/framework/msg.json +0 -0
  191. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/framework/open.js +15 -0
  192. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/framework/restart.js +58 -26
  193. package/framework/v0.1.1-alpha.171/lib/cmd/framework/set.js +264 -0
  194. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/framework/start.js +43 -20
  195. package/framework/v0.1.1-alpha.171/lib/cmd/framework/status.js +138 -0
  196. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/framework/stop.js +44 -28
  197. package/framework/v0.1.1-alpha.171/lib/cmd/framework/tail.js +299 -0
  198. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/framework/update.js +0 -0
  199. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/framework/version.js +12 -3
  200. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/gina-dev.1.md +0 -0
  201. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/gina-framework.1.md +0 -0
  202. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/gina.1.md +0 -0
  203. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/helper.js +74 -5
  204. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/index.js +23 -23
  205. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/msg.json +0 -0
  206. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/port/help.js +0 -0
  207. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/port/help.txt +0 -0
  208. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/port/inc/scan.js +32 -17
  209. package/framework/v0.1.1-alpha.171/lib/cmd/port/list.js +459 -0
  210. package/framework/v0.1.1-alpha.171/lib/cmd/port/reset.js +426 -0
  211. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/port/set.js +0 -0
  212. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/project/add.js +146 -122
  213. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/project/arguments.json +0 -0
  214. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/project/build.js +0 -0
  215. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/project/help.js +0 -0
  216. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/project/help.txt +0 -0
  217. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/project/import.js +0 -0
  218. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/project/list.js +16 -2
  219. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/project/move.js +0 -0
  220. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/project/remove.js +17 -17
  221. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/project/rename.js +0 -0
  222. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/project/restart.js +0 -0
  223. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/project/rm.js +0 -0
  224. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/project/start.js +0 -0
  225. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/project/status.js +0 -0
  226. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/project/stop.js +0 -0
  227. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/protocol/help.js +0 -0
  228. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/protocol/help.txt +0 -0
  229. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/protocol/list.js +0 -0
  230. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/protocol/set.js +239 -201
  231. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/scope/help.js +0 -0
  232. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/scope/help.txt +0 -0
  233. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/scope/link-local.js +0 -0
  234. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/scope/list.js +24 -8
  235. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/scope/remove.js +0 -0
  236. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/scope/rm.js +0 -0
  237. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/scope/set.js +0 -0
  238. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/scope/unset.js +0 -0
  239. package/framework/{v0.1.1-alpha.17/lib/cmd/env → v0.1.1-alpha.171/lib/cmd/scope}/use.js +0 -0
  240. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cmd/view/add.js +34 -9
  241. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/collection/README.md +0 -0
  242. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/collection/build.json +0 -0
  243. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/collection/package.json +1 -1
  244. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/collection/src/main.js +241 -241
  245. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/config.js +31 -30
  246. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cron/README.md +0 -0
  247. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cron/package.json +1 -1
  248. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/cron/src/main.js +10 -9
  249. package/framework/v0.1.1-alpha.171/lib/domain/LICENSE +9 -0
  250. package/framework/v0.1.1-alpha.171/lib/domain/README.md +46 -0
  251. package/framework/v0.1.1-alpha.171/lib/domain/dist/public_suffix_list.dat +14186 -0
  252. package/framework/{v0.1.1-alpha.17/lib/routing/README.md → v0.1.1-alpha.171/lib/domain/exemples/backend.js} +0 -0
  253. package/framework/{v0.1.1-alpha.17/lib/routing/build.json → v0.1.1-alpha.171/lib/domain/exemples/frontend.html} +0 -0
  254. package/framework/v0.1.1-alpha.171/lib/domain/package.json +20 -0
  255. package/framework/v0.1.1-alpha.171/lib/domain/src/main.js +442 -0
  256. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/generator/index.js +4 -4
  257. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/index.js +3 -2
  258. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171/lib/inherits}/LICENSE +1 -1
  259. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/inherits/README.md +2 -2
  260. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/inherits/example/inheriting_eventemitter.js +0 -0
  261. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/inherits/example/protected_inheritance.js +0 -0
  262. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/inherits/example/simple_inheritance.js +0 -0
  263. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/inherits/example/super_attribute_overridden_by_child_on_init.js +0 -0
  264. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/inherits/package.json +3 -4
  265. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/inherits/src/main.js +3 -3
  266. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/logger/README.md +0 -0
  267. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/logger/package.json +2 -2
  268. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/logger/src/containers/default/index.js +13 -2
  269. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/logger/src/containers/file/index.js +105 -14
  270. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/logger/src/containers/file/lib/logrotator/README.md +0 -0
  271. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/logger/src/containers/file/lib/logrotator/index.js +0 -0
  272. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/logger/src/containers/mq/index.js +7 -1
  273. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/logger/src/containers/mq/listener.js +16 -14
  274. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/logger/src/containers/mq/speaker.js +32 -3
  275. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/logger/src/helper.js +21 -1
  276. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/logger/src/main.js +27 -7
  277. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/math/index.js +9 -9
  278. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/merge/README.md +2 -2
  279. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/merge/example/merge.js +0 -0
  280. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/merge/example/merge_2_literal objects.js +0 -0
  281. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/merge/example/merge_and_preserve_first.js +0 -0
  282. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/merge/package.json +1 -1
  283. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/merge/src/main.js +0 -0
  284. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/model.js +10 -10
  285. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/proc.js +87 -49
  286. package/framework/{v0.1.1-alpha.17/lib/swig-filters → v0.1.1-alpha.171/lib/routing}/README.md +0 -0
  287. package/framework/{v0.1.1-alpha.17/lib/url/README.md → v0.1.1-alpha.171/lib/routing/build.json} +0 -0
  288. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/routing/package.json +1 -1
  289. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/routing/src/main.js +270 -264
  290. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/session-store.js +6 -6
  291. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/shell.js +3 -3
  292. package/framework/v0.1.1-alpha.171/lib/swig-filters/README.md +0 -0
  293. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/swig-filters/package.json +1 -1
  294. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/swig-filters/src/main.js +55 -52
  295. package/framework/v0.1.1-alpha.171/lib/url/README.md +0 -0
  296. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/url/index.js +0 -0
  297. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/url/mocks.json +0 -0
  298. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/url/routing.json +0 -0
  299. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/url/test.js +0 -0
  300. package/framework/{v0.1.1-alpha.17 → v0.1.1-alpha.171}/lib/validator.js +2 -2
  301. package/framework/v0.1.1-alpha.171/package.json +14 -0
  302. package/package.json +33 -24
  303. package/resources/home/main.json +44 -1
  304. package/resources/home/settings.json +7 -0
  305. package/resources/home/user/extensions/logger/default/config.json +1 -1
  306. package/resources/package.json.template +29 -18
  307. package/script/post_install.js +411 -123
  308. package/script/post_publish.js +186 -0
  309. package/script/pre_install.js +425 -77
  310. package/script/prepare_version.js +275 -98
  311. package/services/.gna/67fdf1b224a2ed5597e63d4b64283834468e05e3.txt +0 -0
  312. package/services/.gna/arch +1 -0
  313. package/services/.gna/locals.json +14 -0
  314. package/services/.gna/platform +1 -0
  315. package/services/configure +6 -0
  316. package/services/env.json +10 -0
  317. package/services/manifest.json +18 -0
  318. package/services/package.json +11 -0
  319. package/services/src/proxy/config/app.json +6 -0
  320. package/services/src/proxy/config/routing.json +11 -0
  321. package/services/src/proxy/config/settings.json +9 -0
  322. package/services/src/proxy/config/settings.server.json +31 -0
  323. package/services/src/proxy/config/statics.json +3 -0
  324. package/services/src/proxy/controllers/controller.content.js +58 -0
  325. package/services/src/proxy/controllers/controller.js +30 -0
  326. package/{framework/v0.1.1-alpha.17/core/template/boilerplate/bundle → services/src/proxy}/controllers/setup.js +14 -14
  327. package/services/src/proxy/index.js +31 -0
  328. package/services/src/proxy/lib/domain/README.md +48 -0
  329. package/services/src/proxy/lib/domain/src/config/public_suffix_list.dat +14186 -0
  330. package/utils/helper.js +236 -185
  331. package/utils/prototypes.js +9 -9
  332. package/utils/prototypes.json_clone.js +36 -35
  333. package/doc/framework/cli/doc.json +0 -9
  334. package/doc/framework/index.md +0 -60
  335. package/framework/v0.1.1-alpha.17/VERSION +0 -1
  336. package/framework/v0.1.1-alpha.17/core/asset/js/plugin/dist/gina.js.map +0 -56
  337. package/framework/v0.1.1-alpha.17/core/asset/js/plugin/dist/gina.min.css +0 -1
  338. package/framework/v0.1.1-alpha.17/core/asset/js/plugin/dist/gina.min.css.map +0 -1
  339. package/framework/v0.1.1-alpha.17/core/asset/js/plugin/dist/gina.min.js +0 -736
  340. package/framework/v0.1.1-alpha.17/core/asset/js/plugin/dist/gina.min.js.map +0 -56
  341. package/framework/v0.1.1-alpha.17/core/asset/js/plugin/dist/gina.onload.min.js +0 -5
  342. package/framework/v0.1.1-alpha.17/core/asset/js/plugin/dist/gina.onload.min.js.map +0 -8
  343. package/framework/v0.1.1-alpha.17/core/connectors/couchbase/lib/connector.js +0 -20
  344. package/framework/v0.1.1-alpha.17/core/connectors/couchbase/lib/session-store.js +0 -21
  345. package/framework/v0.1.1-alpha.17/core/locales/dist/region/en.json +0 -9492
  346. package/framework/v0.1.1-alpha.17/core/locales/dist/region/fr.json +0 -9492
  347. package/framework/v0.1.1-alpha.17/core/locales/src/resources/region.mapping.json +0 -28
  348. package/framework/v0.1.1-alpha.17/core/template/boilerplate/bundle_templates/html/homepage.html +0 -4
  349. package/framework/v0.1.1-alpha.17/lib/cmd/bundle/arguments.json +0 -4
  350. package/framework/v0.1.1-alpha.17/lib/cmd/bundle/list.js +0 -129
  351. package/framework/v0.1.1-alpha.17/lib/cmd/framework/init.js +0 -514
  352. package/framework/v0.1.1-alpha.17/lib/cmd/framework/set.js +0 -161
  353. package/framework/v0.1.1-alpha.17/lib/cmd/framework/status.js +0 -72
  354. package/framework/v0.1.1-alpha.17/lib/cmd/framework/tail.js +0 -183
  355. package/framework/v0.1.1-alpha.17/lib/cmd/port/list.js +0 -176
  356. package/framework/v0.1.1-alpha.17/package.json +0 -14
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /*
3
3
  * This file is part of the gina package.
4
- * Copyright (c) 2009-2022 Rhinostone <contact@gina.io>
4
+ * Copyright (c) 2009-2023 Rhinostone <contact@gina.io>
5
5
  *
6
6
  * For the full copyright and license information, please view the LICENSE
7
7
  * file that was distributed with this source code.
@@ -19,13 +19,15 @@ var zlib = require('zlib');
19
19
  // var tls = require('tls');
20
20
  // var crypto = require('crypto');
21
21
 
22
- var lib = require('./../../lib') || require.cache[require.resolve('./../../lib')];
22
+ var lib = require('./../../lib') || require.cache[require.resolve('./../../lib')];
23
23
  var merge = lib.merge;
24
24
  var inherits = lib.inherits;
25
25
  var console = lib.logger;
26
26
  var Collection = lib.Collection;
27
- var routingUtils = lib.routing;
27
+ var routingLib = lib.routing;
28
28
  var swig = require('swig');
29
+ // Swig 2
30
+ // var swig = require('./../deps/swig-client/swig-2.0.0.min.js');
29
31
  var SwigFilters = lib.SwigFilters;
30
32
  var statusCodes = requireJSON( _( getPath('gina').core + '/status.codes') );
31
33
 
@@ -44,9 +46,9 @@ function SuperController(options) {
44
46
 
45
47
  //public
46
48
  this.name = 'SuperController';
47
- this.engine = {};
48
-
49
-
49
+ this.engine = {};
50
+
51
+
50
52
  var self = this;
51
53
  //private
52
54
  var local = {
@@ -68,16 +70,16 @@ function SuperController(options) {
68
70
  if ( typeof(SuperController.initialized) != 'undefined' ) {
69
71
  return getInstance()
70
72
  } else {
71
-
73
+
72
74
  SuperController.instance = self;
73
-
74
-
75
+
76
+
75
77
  if (local.options) {
76
78
  SuperController.instance._options = local.options;
77
79
  }
78
-
80
+
79
81
  SuperController.initialized = true;
80
-
82
+
81
83
  }
82
84
  }
83
85
 
@@ -85,46 +87,46 @@ function SuperController(options) {
85
87
  local.options = SuperController.instance._options = options;
86
88
  // 2022-03-07 Fix for none-developpement environnements (without cache)
87
89
  self._options = local.options;
88
-
90
+
89
91
  return SuperController.instance;
90
92
  }
91
93
 
92
94
  var hasViews = function() {
93
95
  return ( typeof(local.options.template) != 'undefined' ) ? true : false;
94
96
  }
95
-
97
+
96
98
  /**
97
99
  * isHttp2
98
100
  * Returns `true` if server configured for HTTP/2
99
- *
101
+ *
100
102
  * @returns {boolean} isHttp2
101
103
  */
102
104
  var isHttp2 = function() {
103
- var options = local.options;
105
+ var options = local.options;
104
106
  var protocolVersion = ~~options.conf.server.protocol.match(/\/(.*)$/)[1].replace(/\.\d+/, '');
105
107
  var httpLib = options.conf.server.protocol.match(/^(.*)\//)[1] + ( (protocolVersion >= 2) ? protocolVersion : '' );
106
-
107
-
108
+
109
+
108
110
  return /http2/.test(httpLib)
109
111
  }
110
112
  /**
111
113
  * isSecured
112
114
  * Returns `true` if server configured to handle a HTTPS exchanges
113
- *
115
+ *
114
116
  * @returns {boolean} isSecured
115
117
  */
116
118
  var isSecured = function() {
117
119
  return /https/.test(local.options.conf.server.scheme)
118
120
  }
119
-
121
+
120
122
  this.getRequestObject = function() {
121
123
  return local.req;
122
124
  }
123
-
125
+
124
126
  this.getResponseObject = function() {
125
127
  return local.res;
126
128
  }
127
-
129
+
128
130
  this.getNextCallback = function() {
129
131
  return local.next;
130
132
  }
@@ -146,7 +148,7 @@ function SuperController(options) {
146
148
  local.options = SuperController.instance._options = options;
147
149
  local.options.renderingStack = (local.options.renderingStack) ? local.options.renderingStack : [];
148
150
  local.options.isRenderingCustomError = (local.options.isRenderingCustomError) ? local.options.isRenderingCustomError : false;
149
-
151
+
150
152
 
151
153
  // N.B.: Avoid setting `page` properties as much as possible from the routing.json
152
154
  // It will be easier for the framework if set from the controller.
@@ -169,12 +171,12 @@ function SuperController(options) {
169
171
  // var data = { page: { view: { title: "My Title"}}};
170
172
  // self.render(data)
171
173
  // }
172
-
174
+
173
175
  if ( typeof(options.conf.content.routing[options.rule].param) != 'undefined' ) {
174
176
  var str = 'page.'
175
177
  , p = options.conf.content.routing[options.rule].param
176
178
  ;
177
-
179
+
178
180
  for (var key in p) {
179
181
  if ( p.hasOwnProperty(key) && !/^(control)$/.test(key) ) {
180
182
  str += key + '.';
@@ -213,23 +215,23 @@ function SuperController(options) {
213
215
  , rule = local.options.rule
214
216
  , ext = 'html' // by default
215
217
  , isWithoutLayout = false // by default
216
- , namespace = local.options.namespace || '';
218
+ , namespace = local.options.namespace || '';
217
219
 
218
220
 
219
221
  if ( typeof(local.options.template) != 'undefined' && local.options.template ) {
220
- if (
221
- typeof(local.options.template.ext) != 'undefined'
222
- && local.options.template.ext
222
+ if (
223
+ typeof(local.options.template.ext) != 'undefined'
224
+ && local.options.template.ext
223
225
  && local.options.template.ext != ''
224
226
  ) {
225
227
  ext = local.options.template.ext
226
228
  }
227
-
229
+
228
230
  if ( !/\./.test(ext) ) {
229
231
  ext = '.' + ext;
230
232
  local.options.template.ext = ext
231
233
  }
232
-
234
+
233
235
  if (
234
236
  typeof(local.options.template.layout) == 'undefined'
235
237
  || /^false$/.test(local.options.template.layout)
@@ -238,27 +240,27 @@ function SuperController(options) {
238
240
  isWithoutLayout = true;
239
241
  }
240
242
  }
241
-
242
-
243
+
244
+
243
245
  if ( hasViews() ) {
244
246
 
245
247
  if ( typeof(local.options.file) == 'undefined') {
246
248
  local.options.file = 'index'
247
249
  }
248
-
250
+
249
251
  if ( typeof(local.options.isWithoutLayout) == 'undefined' || !isWithoutLayout ) {
250
252
  local.options.isWithoutLayout = false;
251
253
  }
252
-
254
+
253
255
  rule = local.options.rule;
254
- namespace = local.options.namespace || 'default';
255
-
256
-
256
+ namespace = local.options.namespace || 'default';
257
+
258
+
257
259
  set('page.view.file', local.options.file);
258
260
  set('page.view.title', rule.replace(new RegExp('@' + options.conf.bundle), ''));
259
261
  set('page.view.namespace', namespace);
260
- }
261
-
262
+ }
263
+
262
264
 
263
265
  var ctx = getContext('gina');
264
266
  // new declaration && overrides
@@ -270,6 +272,8 @@ function SuperController(options) {
270
272
  "middleware" : ctx.middleware
271
273
  };
272
274
 
275
+ set('page.environment.allocated memory', (require('v8').getHeapStatistics().heap_size_limit / (1024 * 1024 * 1024)).toFixed(2) +' GB');
276
+
273
277
  set('page.environment.gina', version.number);
274
278
  set('page.environment.gina pid', GINA_PID);
275
279
  set('page.environment.nodejs', version.nodejs +' '+ version.platform +' '+ version.arch);
@@ -277,19 +281,20 @@ function SuperController(options) {
277
281
  set('page.environment.env', process.env.NODE_ENV);
278
282
  set('page.environment.envIsDev', self.isCacheless());
279
283
  set('page.environment.date.now', new Date().format("isoDateTime"));
280
-
281
-
284
+
285
+
282
286
  var routing = local.options.conf.routing = ctx.config.envConf.routing; // all routes
283
287
  set('page.environment.routing', escape(JSON.stringify(routing))); // export for GFF
284
288
  //reverseRouting
285
289
  var reverseRouting = local.options.conf.reverseRouting = ctx.config.envConf.reverseRouting; // all routes
286
290
  set('page.environment.reverseRouting', escape(JSON.stringify(reverseRouting))); // export for GFF
287
-
291
+
288
292
  var forms = local.options.conf.forms = options.conf.content.forms // all forms
289
293
  set('page.environment.forms', escape(JSON.stringify(forms))); // export for GFF
290
294
  set('page.forms', options.conf.content.forms);
291
-
295
+
292
296
  set('page.environment.hostname', ctx.config.envConf[options.conf.bundle][process.env.NODE_ENV].hostname);
297
+ set('page.environment.rootDomain', ctx.config.envConf[options.conf.bundle][process.env.NODE_ENV].rootDomain);
293
298
  set('page.environment.webroot', options.conf.server.webroot);
294
299
  set('page.environment.bundle', options.conf.bundle);
295
300
  set('page.environment.project', options.conf.projectName);
@@ -298,14 +303,14 @@ function SuperController(options) {
298
303
  set('page.environment.port', options.conf.server.port);
299
304
  set('page.environment.debugPort', options.conf.server.debugPort);
300
305
  set('page.environment.pid', process.pid);
301
-
302
-
306
+
307
+
303
308
  set('page.view.ext', ext);
304
309
  set('page.view.control', action);
305
310
  set('page.view.controller', local.options.controller.replace(options.conf.bundlesPath, ''), true);
306
311
  if (typeof (local.options.controlRequired) != 'undefined' ) {
307
312
  set('page.view.controlRequired', local.options.controlRequired);
308
- }
313
+ }
309
314
  set('page.view.method', local.options.method);
310
315
  set('page.view.namespace', namespace); // by default
311
316
  set('page.view.url', req.url);
@@ -314,12 +319,12 @@ function SuperController(options) {
314
319
  set('page.view.html.properties.mode.javascriptsDeferEnabled', local.options.template.javascriptsDeferEnabled);
315
320
  set('page.view.html.properties.mode.routeNameAsFilenameEnabled', local.options.template.routeNameAsFilenameEnabled);
316
321
  }
317
-
318
-
322
+
323
+
319
324
  var parameters = JSON.clone(req.getParams());
320
325
  parameters = merge(parameters, options.conf.content.routing[rule].param);
321
326
  // excluding default page properties
322
- delete parameters[0];
327
+ delete parameters[0];
323
328
  delete parameters.file;
324
329
  delete parameters.control;
325
330
  delete parameters.title;
@@ -329,7 +334,7 @@ function SuperController(options) {
329
334
 
330
335
  set('page.view.route', rule);
331
336
 
332
-
337
+
333
338
  var acceptLanguage = GINA_CULTURE; // by default : language-COUNTRY
334
339
  if ( typeof(req.headers['accept-language']) != 'undefined' ) {
335
340
  acceptLanguage = req.headers['accept-language']
@@ -348,8 +353,8 @@ function SuperController(options) {
348
353
 
349
354
  try {
350
355
  userLocales = locales.findOne({ lang: userLangCode }).content;
351
- } catch (err) {
352
- //var defaultRegion = (local.options.conf.content.settings.region) ? local.options.conf.content.settings.region.shortCode
356
+ } catch (err) {
357
+ //var defaultRegion = (local.options.conf.content.settings.region) ? local.options.conf.content.settings.region.shortCode
353
358
  console.warn('language code `'+ userLangCode +'` not handled by current locales setup: replacing by default: `'+ local.options.conf.content.settings.region.shortCode +'`');
354
359
  userLocales = locales.findOne({ lang: local.options.conf.content.settings.region.shortCode }).content // by default
355
360
  }
@@ -359,7 +364,7 @@ function SuperController(options) {
359
364
 
360
365
  // user locale
361
366
  options.conf.locale = new Collection(userLocales).findOne({ short: userCountryCode }) || {};
362
-
367
+
363
368
  //set('page.date.now', new Date().format("isoDateTime"));
364
369
  if ( typeof(options.conf.locale) == 'undefined' || !options.conf.locale ) {
365
370
  options.conf.locale = {}
@@ -370,22 +375,22 @@ function SuperController(options) {
370
375
  set('page.view.locale', options.conf.locale);
371
376
  set('page.view.lang', userCulture);
372
377
  }
373
-
378
+
374
379
  if ( !getContext('isProxyHost') ) {
375
380
  var isProxyHost = ( typeof(req.headers.host) != 'undefined' && local.options.conf.server.scheme +'://'+ req.headers.host != local.options.conf.hostname || typeof(req.headers[':authority']) != 'undefined' && local.options.conf.server.scheme +'://'+ req.headers[':authority'] != local.options.conf.hostname ) ? true : false;
376
381
  setContext('isProxyHost', isProxyHost);
377
382
  }
378
-
383
+
379
384
  //TODO - detect when to use swig
380
385
  var dir = null;
381
386
  if (local.options.template || self.templates) {
382
387
  dir = local.options.template.templates || self.templates;
383
-
388
+
384
389
  var swigOptions = {
385
390
  autoescape : ( typeof(local.options.autoescape) != 'undefined') ? local.options.autoescape : false,
386
391
  // `memory` is no working yet ... advanced rendering setup required
387
- //cache : (local.options.cacheless) ? false : 'memory'
388
- cache : false
392
+ cache : (local.options.cacheless) ? false : 'memory'
393
+ // cache : 'memory'
389
394
  };
390
395
  if (dir) {
391
396
  swigOptions.loader = swig.loaders.fs(dir);
@@ -401,11 +406,11 @@ function SuperController(options) {
401
406
  // preserve the same timezone as the system
402
407
  var defaultTZOffset = new Date().getTimezoneOffset();
403
408
  swig.setDefaultTZOffset(defaultTZOffset);
404
-
409
+
405
410
  self.engine = swig;
406
411
  }
407
412
  }
408
-
413
+
409
414
  this.renderWithoutLayout = function (data, displayToolbar) {
410
415
 
411
416
  // preventing multiple call of self.renderWithoutLayout() when controller is rendering from another required controller
@@ -414,7 +419,7 @@ function SuperController(options) {
414
419
  }
415
420
 
416
421
  local.options.isWithoutLayout = true;
417
-
422
+
418
423
  self.render(data, displayToolbar);
419
424
  }
420
425
 
@@ -444,47 +449,52 @@ function SuperController(options) {
444
449
  ) ? true : false;
445
450
  if (isRenderingCustomError)
446
451
  delete userData.isRenderingCustomError;
447
-
452
+
448
453
  var localOptions = (errOptions) ? errOptions : local.options;
449
454
  localOptions.renderingStack.push( self.name );
450
455
  // preventing multiple call of self.render() when controller is rendering from another required controller
451
456
  if ( localOptions.renderingStack.length > 1 && !isRenderingCustomError ) {
452
457
  return false
453
458
  }
454
-
455
-
459
+
460
+
456
461
  var data = null
457
462
  , layout = null
458
463
  , template = null
459
464
  , file = null
460
465
  , path = null
461
466
  , plugin = null
462
- , isWithoutLayout = (localOptions.isWithoutLayout) ? true : false
467
+ , isWithoutLayout = (localOptions.isWithoutLayout) ? true : false
463
468
  ;
464
-
469
+
465
470
  localOptions.debugMode = ( typeof(displayToolbar) == 'undefined' ) ? undefined : ( (/true/i.test(displayToolbar)) ? true : false ); // only active for dev env
466
-
471
+
467
472
  // specific override
468
473
  if (
469
474
  self.isCacheless()
470
- && typeof(local.req[ local.req.method.toLowerCase() ]) != 'undefined'
471
- && typeof(local.req[ local.req.method.toLowerCase() ].debug) != 'undefined'
475
+ && typeof(local.req[ local.req.method.toLowerCase() ]) != 'undefined'
476
+ && typeof(local.req[ local.req.method.toLowerCase() ].debug) != 'undefined'
472
477
  ) {
473
- localOptions.debugMode = ( /true/i.test(local.req[ local.req.method.toLowerCase() ].debug) ) ? true : false;
474
- } else if (
475
- self.isCacheless()
478
+ if ( !/^(true|false)$/i.test(local.req[ local.req.method.toLowerCase() ].debug) ) {
479
+ console.warn('Detected wrong value for `debug`: '+ local.req[ local.req.method.toLowerCase() ].debug);
480
+ console.warn('Switching `debug` to `true` as `cacheless` mode is enabled');
481
+ local.req[ local.req.method.toLowerCase() ].debug = true;
482
+ }
483
+ localOptions.debugMode = ( /^true$/i.test(local.req[ local.req.method.toLowerCase() ].debug) ) ? true : false;
484
+ } else if (
485
+ self.isCacheless()
476
486
  && hasViews()
477
- && !isWithoutLayout
478
- && localOptions.debugMode == undefined
487
+ && !isWithoutLayout
488
+ && localOptions.debugMode == undefined
479
489
  ) {
480
490
  localOptions.debugMode = true;
481
491
  } else if ( localOptions.debugMode == undefined ) {
482
492
  localOptions.debugMode = self.isCacheless()
483
493
  }
484
-
494
+
485
495
  try {
486
496
  data = getData();
487
-
497
+
488
498
  if (!userData) {
489
499
  userData = { page: { view: {}}}
490
500
  } else if ( userData && !userData['page']) {
@@ -502,7 +512,7 @@ function SuperController(options) {
502
512
  if ( isWithoutLayout ) {
503
513
  localTemplateConf = JSON.clone(localOptions.template);
504
514
  localTemplateConf.javascripts = new Collection(localTemplateConf.javascripts).find({ isCommon: false}, { isCommon: true, name: 'gina' });
505
- localTemplateConf.stylesheets = new Collection(localTemplateConf.stylesheets).find({ isCommon: false}, { isCommon: true, name: 'gina' });
515
+ localTemplateConf.stylesheets = new Collection(localTemplateConf.stylesheets).find({ isCommon: false}, { isCommon: true, name: 'gina' });
506
516
  }
507
517
  setResources(localTemplateConf);
508
518
  // Allowing file & ext override
@@ -512,13 +522,13 @@ function SuperController(options) {
512
522
  ) {
513
523
  data.page.view.file = localOptions.file = local.req.routing.param.file
514
524
  }
515
- if (
516
- typeof(local.req.routing.param.ext) != 'undefined'
525
+ if (
526
+ typeof(local.req.routing.param.ext) != 'undefined'
517
527
  && data.page.view.ext !== local.req.routing.param.ext
518
528
  ) {
519
529
  data.page.view.ext = localOptions.template.ext = local.req.routing.param.ext
520
530
  }
521
-
531
+
522
532
  file = (isRenderingCustomError) ? localOptions.file : data.page.view.file;
523
533
 
524
534
  // pre-compiling variables
@@ -527,13 +537,13 @@ function SuperController(options) {
527
537
  if (typeof(data.page.data) == 'undefined' ) {
528
538
  data.page.data = {}
529
539
  }
530
-
531
540
 
532
- if (
541
+
542
+ if (
533
543
  !local.options.isRenderingCustomError
534
- && typeof(data.page.data.status) != 'undefined'
535
- && !/^2/.test(data.page.data.status)
536
- && typeof(data.page.data.error) != 'undefined'
544
+ && typeof(data.page.data.status) != 'undefined'
545
+ && !/^2/.test(data.page.data.status)
546
+ && typeof(data.page.data.error) != 'undefined'
537
547
  ) {
538
548
  var statusCode = localOptions.conf.server.coreConfiguration.statusCodes;
539
549
  var errorObject = {
@@ -555,9 +565,9 @@ function SuperController(options) {
555
565
  // excepted for custom paths
556
566
  if ( !/^(\.|\/|\\)/.test(file) )
557
567
  file = ''+ file.replace(localOptions.namespace+'-', '');
558
-
568
+
559
569
  // means that rule name === namespace -> pointing to root namespace dir
560
- if (!file || file === localOptions.namespace) {
570
+ if (!file || file === localOptions.namespace) {
561
571
  file = 'index'
562
572
  }
563
573
  path = (isRenderingCustomError) ? _(file) : _(localOptions.template.html +'/'+ localOptions.namespace + '/' + file)
@@ -593,14 +603,14 @@ function SuperController(options) {
593
603
  dic['page.'+d] = data.page[d]
594
604
  }
595
605
 
596
-
606
+
597
607
 
598
608
  // please, do not start with a slashe when including...
599
609
  // ex.:
600
610
  // /html/inc/_partial.html (BAD)
601
611
  // html/inc/_partial.html (GOOD)
602
612
  // ./html/namespace/page.html (GOOD)
603
-
613
+
604
614
  if ( !fs.existsSync(path) ) {
605
615
  msg = 'could not open "'+ path +'"' +
606
616
  '\n1) The requested file does not exists in your templates/html (check your template directory). Can you find: '+path +
@@ -614,32 +624,32 @@ function SuperController(options) {
614
624
  self.throwError(err);
615
625
  return;
616
626
  }
617
-
618
- var isProxyHost = (
619
- typeof(local.req.headers.host) != 'undefined'
620
- && localOptions.conf.server.scheme +'://'+ local.req.headers.host != localOptions.conf.hostname
621
- || typeof(local.req.headers[':authority']) != 'undefined'
622
- && localOptions.conf.server.scheme +'://'+ local.req.headers[':authority'] != localOptions.conf.hostname
627
+
628
+ var isProxyHost = (
629
+ typeof(local.req.headers.host) != 'undefined'
630
+ && localOptions.conf.server.scheme +'://'+ local.req.headers.host != localOptions.conf.hostname
631
+ || typeof(local.req.headers[':authority']) != 'undefined'
632
+ && localOptions.conf.server.scheme +'://'+ local.req.headers[':authority'] != localOptions.conf.hostname
623
633
  ) ? true : false;
624
- // setup swig default filters
634
+ // setup swig default filters
625
635
  var filters = SwigFilters({
626
636
  options : JSON.clone(localOptions),
627
637
  isProxyHost : isProxyHost,
628
638
  throwError : self.throwError,
629
639
  req : local.req,
630
- res : local.res
640
+ res : local.res
631
641
  });
632
642
 
633
643
  try {
634
-
644
+
635
645
  // Extends default `length` filter
636
646
  swig.setFilter('length', filters.length);
637
647
 
638
-
648
+
639
649
 
640
650
  // Allows you to get a bundle web root
641
651
  swig.setFilter('getWebroot', filters.getWebroot);
642
-
652
+
643
653
  swig.setFilter('getUrl', filters.getUrl);
644
654
 
645
655
  } catch (err) {
@@ -651,10 +661,10 @@ function SuperController(options) {
651
661
  self.throwError(local.res, 500, new Error('template compilation exception encoutered: [ '+path+' ]\n'+(err.stack||err.message)));
652
662
  return;
653
663
  }
654
-
655
-
656
-
657
- var layoutPath = null
664
+
665
+
666
+
667
+ var layoutPath = null
658
668
  , assets = null
659
669
  , mapping = null
660
670
  , XHRData = null
@@ -665,26 +675,26 @@ function SuperController(options) {
665
675
  , isWithSwigLayout = null
666
676
  , isUsingGinaLayout = (!isWithoutLayout && typeof(localOptions.template.layout) != 'undefined' && fs.existsSync(local.options.template.layout)) ? true : false
667
677
  ;
668
-
669
- if ( isWithoutLayout || isUsingGinaLayout ) {
678
+
679
+ if ( isWithoutLayout || isUsingGinaLayout ) {
670
680
  layoutPath = (isWithoutLayout) ? localOptions.template.noLayout : localOptions.template.layout;
671
681
  // user layout override
672
- if ( isUsingGinaLayout && !isWithoutLayout ) {
682
+ if ( isUsingGinaLayout && !isWithoutLayout ) {
673
683
  layoutPath = localOptions.template.layout;
674
- }
684
+ }
675
685
  if (isWithoutLayout) {
676
686
  data.page.view.layout = layoutPath;
677
- }
687
+ }
678
688
  } else { // without layout case
679
-
689
+
680
690
  // by default
681
691
  layoutPath = localOptions.template.layout;
682
692
  if ( !/^\//.test(layoutPath)) {
683
693
  layoutPath = localOptions.template.templates +'/'+ layoutPath;
684
694
  }
685
695
  // default layout
686
- if (
687
- !isWithoutLayout && !fs.existsSync(layoutPath) && layoutPath == localOptions.template.templates +'/index.html'
696
+ if (
697
+ !isWithoutLayout && !fs.existsSync(layoutPath) && layoutPath == localOptions.template.templates +'/index.html'
688
698
  ) {
689
699
  console.warn('Layout '+ local.options.template.layout +' not found, replacing with `nolayout`: '+ localOptions.template.noLayout);
690
700
  layoutPath = localOptions.template.noLayout
@@ -703,57 +713,57 @@ function SuperController(options) {
703
713
  self.throwError(err);
704
714
  return;
705
715
  }
706
-
716
+
707
717
  }
708
-
709
-
718
+
719
+
710
720
  var isLoadingPartial = false;
711
- try {
721
+ try {
712
722
  assets = {assets:"${assets}"};
713
-
723
+
714
724
  /**
715
725
  * retrieve template & layout
716
- * */
717
- var tpl = null;
726
+ * */
727
+ var tpl = null;
718
728
  // tpl = fs.readFileSync(path).toString();
719
- // layout = fs.readFileSync(layoutPath).toString();
720
-
729
+ // layout = fs.readFileSync(layoutPath).toString();
730
+
721
731
  await Promise.all([
722
- readFile(layoutPath),
723
- readFile(path)
732
+ readFile(layoutPath),
733
+ readFile(path)
724
734
  ])
725
- .then(([_layout, _tpl]) => {
735
+ .then(([_layout, _tpl]) => {
726
736
  layout = _layout.toString();
727
737
  tpl = _tpl.toString();
728
738
  })
729
739
  .catch(error => {
730
- console.error(error.message);
731
- return;
732
- });
733
-
734
-
740
+ console.error(error.message);
741
+ return;
742
+ });
743
+
744
+
735
745
  // mappin conf
736
746
  mapping = { filename: path };
737
747
  if (isRenderingCustomError) {
738
748
  // TODO - Test if there is a block call `gina-error` in the layout & replace block name from tpl
739
-
749
+
740
750
  if ( !/\{\%(\s+extends|extends)/.test(tpl) ) {
741
751
  tpl = "\n{% extends '"+ layoutPath +"' %}\n" + tpl;
742
752
  }
743
753
  if (!/\{\% block content/.test(tpl)) {
744
754
  // TODO - test if lyout has <body>
745
755
  tpl = '{% block content %}<p>If you view this message you didn’t define a content block in your template.</p>{% endblock %}' + tpl;
746
- }
747
-
756
+ }
757
+
748
758
  tpl = tpl.replace(/\{\{ page\.content \}\}/g, '');
749
759
  }
750
-
760
+
751
761
  if ( isWithoutLayout || isWithSwigLayout) {
752
- layout = tpl;
762
+ layout = tpl;
753
763
  } else if (isUsingGinaLayout) {
754
764
  mapping = { filename: path };
755
765
  if ( /(\{\{|\{\{\s+)page\.content/.test(layout) ) {
756
-
766
+
757
767
  if ( /\{\%(\s+extends|extends)/.test(tpl) ) {
758
768
  err = new Error('You cannot use at the same time `page.content` in your layout `'+ layoutPath +'` while calling `extends` from your page or content `'+ path +'`. You have to choose one or the other');
759
769
  self.throwError(local.res, 500, err);
@@ -761,9 +771,9 @@ function SuperController(options) {
761
771
  }
762
772
  layout = layout.replace('{{ page.content }}', tpl);
763
773
  } else {
764
- layout = layout.replace(/\<\/body\>/i, '\t'+tpl+'\n</body>');
774
+ layout = layout.replace(/\<\/body\>/i, '\t'+tpl+'\n</body>');
765
775
  }
766
-
776
+
767
777
  } else {
768
778
  tpl = tpl.replace('{{ page.view.layout }}', data.page.view.layout);
769
779
  if (/\<\/body\>/i.test(layout)) {
@@ -771,78 +781,81 @@ function SuperController(options) {
771
781
  }
772
782
  else {
773
783
  layout += tpl;
774
- }
784
+ }
775
785
  }
776
-
786
+
777
787
  // precompilation needed in case of `extends` or in order to display the toolbar
778
- if ( hasViews() && self.isCacheless() || /\{\%(\s+extends|extends)/.test(layout) ) {
788
+ if ( hasViews() && self.isCacheless() || /\{\%(\s+extends|extends)/.test(layout) ) {
779
789
  layout = swig.compile(layout, mapping)(data);
780
790
  }
781
- //dic['page.content'] = layout;
782
-
791
+ //dic['page.content'] = layout;
792
+
783
793
  } catch(err) {
784
794
  err.stack = 'Exception, bad syntax or undefined data found: start investigating in '+ mapping.filename +'\n' + err.stack;
785
795
  self.throwError(local.res, 500, err);
786
796
  return
787
797
  }
788
-
789
- isLoadingPartial = (
790
- !/\<html/i.test(layout)
791
- || !/\<head/i.test(layout)
792
- || !/\<body/i.test(layout)
798
+
799
+ isLoadingPartial = (
800
+ !/\<html/i.test(layout)
801
+ || !/\<head/i.test(layout)
802
+ || !/\<body/i.test(layout)
793
803
  ) ? true : false;
794
-
804
+
795
805
  // if (isLoadingPartial) {
796
806
  // console.warn('----------------> loading partial `'+ path);
797
807
  // }
798
-
799
- isDeferModeEnabled = localOptions.template.javascriptsDeferEnabled || localOptions.conf.content.templates._common.javascriptsDeferEnabled || false;
800
-
808
+
809
+ isDeferModeEnabled = localOptions.template.javascriptsDeferEnabled || localOptions.conf.content.templates._common.javascriptsDeferEnabled || false;
810
+
801
811
  // iframe case - without HTML TAG
802
812
  if (!self.isXMLRequest() && !/\<html/.test(layout) ) {
803
813
  layout = '<html>\n\t<head></head>\n\t<body class="gina-iframe-body">\n\t\t'+ layout +'\n\t</body>\n</html>';
804
- }
805
-
814
+ }
815
+
806
816
  // adding stylesheets
807
817
  if (!isWithoutLayout && data.page.view.stylesheets && !/\{\{\s+(page\.view\.stylesheets)\s+\}\}/.test(layout) ) {
808
818
  layout = layout.replace(/\<\/head\>/i, '\n\t{{ page.view.stylesheets }}\n</head>')
809
819
  }
810
-
820
+
811
821
  if (hasViews() && isWithoutLayout) {
812
822
  // $.getScript(...)
813
823
  //var isProxyHost = ( typeof(local.req.headers.host) != 'undefined' && localOptions.conf.server.scheme +'://'+ local.req.headers.host != localOptions.conf.hostname || typeof(local.req.headers[':authority']) != 'undefined' && localOptions.conf.server.scheme +'://'+ local.req.headers[':authority'] != localOptions.conf.hostname ) ? true : false;
814
824
  //var hostname = (isProxyHost) ? localOptions.conf.hostname.replace(/\:\d+$/, '') : localOptions.conf.hostname;
815
-
816
-
817
-
825
+
826
+
827
+
818
828
  var scripts = data.page.view.scripts;
819
829
  scripts = scripts.replace(/\s+\<script/g, '\n<script');
820
-
830
+
821
831
  if (!isProxyHost) {
822
832
  var webroot = data.page.environment.webroot;
823
833
  scripts = scripts.replace(/src\=\"\/(.*)\"/g, 'src="'+ webroot +'$1"');
824
834
  //stylesheets = stylesheets.replace(/href\=\"\/(.*)\"/g, 'href="'+ webroot +'$1"')
825
835
  }
826
-
836
+
827
837
  // iframe case - without HTML TAG
828
- if (self.isXMLRequest() || !/\<html/.test(layout) ) {
829
- layout += scripts;
830
- //layout += stylesheets;
831
- }
832
-
838
+ if (self.isXMLRequest() || !/\<html/.test(layout) ) {
839
+ layout += scripts;
840
+ //layout += stylesheets;
841
+ }
842
+
833
843
  }
834
844
 
835
845
  // adding plugins
836
-
837
-
846
+ // means that we don't want GFF context or we already have it loaded
847
+ viewInfos = JSON.clone(data.page.view);
848
+ if ( !isWithoutLayout )
849
+ viewInfos.assets = assets;
850
+
838
851
  if (
839
- hasViews() && self.isCacheless() && !isWithoutLayout
840
- && localOptions.debugMode
841
- ||
842
- hasViews() && self.isCacheless() && !isWithoutLayout
843
- && typeof(localOptions.debugMode) == 'undefined'
844
- ||
845
- hasViews() && localOptions.debugMode
852
+ hasViews() && self.isCacheless() && !isWithoutLayout
853
+ && localOptions.debugMode
854
+ ||
855
+ hasViews() && self.isCacheless() && !isWithoutLayout
856
+ && typeof(localOptions.debugMode) == 'undefined'
857
+ ||
858
+ hasViews() && localOptions.debugMode
846
859
  ) {
847
860
 
848
861
  layout = ''
@@ -852,57 +865,64 @@ function SuperController(options) {
852
865
  + '{%- set ginaDataInspector.view.stylesheets = "ignored-by-toolbar" -%}'
853
866
  + layout
854
867
  ;
855
-
868
+
856
869
  plugin = '\t'
857
870
  + '{# Gina Toolbar #}'
858
871
  + '{%- set userDataInspector = JSON.clone(page) -%}'
859
872
  + '{%- set userDataInspector.view.scripts = "ignored-by-toolbar" -%}'
860
873
  + '{%- set userDataInspector.view.stylesheets = "ignored-by-toolbar" -%}'
861
874
  + '{%- set userDataInspector.view.assets = '+ JSON.stringify(assets) +' -%}'
862
- + '{%- include "'+ getPath('gina').core +'/asset/js/plugin/src/gina/toolbar/toolbar.html" with { gina: ginaDataInspector, user: userDataInspector } -%}'
863
- + '{# END Gina Toolbar #}'
875
+ + '{%- include "'+ getPath('gina').core +'/asset/plugin/dist/vendor/gina/html/toolbar.html" with { gina: ginaDataInspector, user: userDataInspector } -%}'// jshint ignore:line
876
+ + '{# END Gina Toolbar #}'
864
877
  ;
865
-
878
+
866
879
 
867
880
  if (isWithoutLayout && localOptions.debugMode || localOptions.debugMode ) {
868
881
 
869
882
  XHRData = '\t<input type="hidden" id="gina-without-layout-xhr-data" value="'+ encodeURIComponent(JSON.stringify(data.page.data)) +'">\n\r';
870
-
871
- layout = layout.replace(/<\/body>/i, XHRData + '\n\t</body>');
883
+ XHRView = '\n<input type="hidden" id="gina-without-layout-xhr-view" value="'+ encodeURIComponent(JSON.stringify(viewInfos)) +'">';
884
+ if ( /<\/body>/i.test(layout) ) {
885
+ layout = layout.replace(/<\/body>/i, XHRData + XHRView + '\n\t</body>');
886
+ } else {
887
+ // Popin case
888
+ // Fix added on 2023-01-25
889
+ layout += XHRData + XHRView + '\n\t'
890
+ }
891
+
872
892
  }
873
-
893
+
874
894
  if (self.isCacheless() || localOptions.debugMode ) {
875
895
  layout = layout.replace(/<\/body>/i, plugin + '\n\t</body>');
876
896
  }
877
-
897
+
878
898
  // adding javascripts
879
- layout.replace('{{ page.view.scripts }}', '');
899
+ layout.replace('{{ page.view.scripts }}', '');
880
900
  // placed in the HEAD excepted when rendering a partial or when `isDeferModeEnabled` == true
881
901
  if (isLoadingPartial) {
882
902
  layout += '\t{{ page.view.scripts }}';
883
903
  } else {
884
904
  if ( isDeferModeEnabled ) {
885
905
  layout = layout.replace(/\<\/head\>/i, '\t{{ page.view.scripts }}\n\t</head>');
886
- } else { // placed in the BODY
906
+ } else { // placed in the BODY
887
907
  layout = layout.replace(/\<\/body\>/i, '\t{{ page.view.scripts }}\n</body>');
888
908
  }
889
909
  }
890
-
910
+
891
911
  // ginaLoader cannot be deferred
892
912
  if ( !localOptions.template.javascriptsExcluded || localOptions.template.javascriptsExcluded != '**' ) {
893
- layout = layout.replace(/\<\/head\>/i, '\t'+ localOptions.template.ginaLoader +'\n</head>');
913
+ layout = layout.replace(/\<\/head\>/i, '\t'+ localOptions.template.ginaLoader +'\n</head>');
894
914
  }
895
915
 
896
916
  } else if ( hasViews() && self.isCacheless() && self.isXMLRequest() ) {
897
-
898
- if (isWithoutLayout) {
917
+
918
+ if (isWithoutLayout) {
899
919
  delete data.page.view.scripts;
900
- delete data.page.view.stylesheets;
920
+ delete data.page.view.stylesheets;
901
921
  }
902
922
  // means that we don't want GFF context or we already have it loaded
903
- viewInfos = JSON.clone(data.page.view);
904
- if ( !isWithoutLayout )
905
- viewInfos.assets = assets;
923
+ // viewInfos = JSON.clone(data.page.view);
924
+ // if ( !isWithoutLayout )
925
+ // viewInfos.assets = assets;
906
926
 
907
927
  XHRData = '\n<input type="hidden" id="gina-without-layout-xhr-data" value="'+ encodeURIComponent(JSON.stringify(data.page.data)) +'">';
908
928
  XHRView = '\n<input type="hidden" id="gina-without-layout-xhr-view" value="'+ encodeURIComponent(JSON.stringify(viewInfos)) +'">';
@@ -911,38 +931,38 @@ function SuperController(options) {
911
931
  layout += XHRData + XHRView;
912
932
 
913
933
  } else { // other envs like prod ...
914
-
934
+
915
935
  // adding javascripts
916
936
  // cleanup first
917
- layout.replace('{{ page.view.scripts }}', '');
937
+ layout.replace('{{ page.view.scripts }}', '');
918
938
  // placed in the HEAD excepted when rendering a partial or when `isDeferModeEnabled` == true
919
939
  // if (isLoadingPartial) {
920
940
  // layout += '\t{{ page.view.scripts }}';
921
941
  // } else {
922
942
  // if ( isDeferModeEnabled ) {
923
943
  // layout = layout.replace(/\<\/head\>/i, '\t{{ page.view.scripts }}\n\t</head>');
924
- // } else { // placed in the BODY
944
+ // } else { // placed in the BODY
925
945
  // layout = layout.replace(/\<\/body\>/i, '\t{{ page.view.scripts }}\n</body>');
926
946
  // }
927
947
  // }
928
-
948
+
929
949
  // // ginaLoader cannot be deferred
930
950
  // if ( !localOptions.template.javascriptsExcluded || localOptions.template.javascriptsExcluded != '**' ) {
931
- // layout = layout.replace(/\<\/head\>/i, '\t'+ localOptions.template.ginaLoader +'\n</head>');
951
+ // layout = layout.replace(/\<\/head\>/i, '\t'+ localOptions.template.ginaLoader +'\n</head>');
932
952
  // }
933
-
953
+
934
954
  // adding javascripts
935
955
  layout.replace('{{ page.view.scripts }}', '');
936
- if (isLoadingPartial) {
956
+ if (isLoadingPartial) {
937
957
  layout += '\t{{ page.view.scripts }}\n';
938
958
  if ( !localOptions.template.javascriptsExcluded || localOptions.template.javascriptsExcluded != '**' ) {
939
959
  layout += '\t'+ localOptions.template.ginaLoader +'\n';
940
960
  }
941
961
  } else {
942
- if ( isDeferModeEnabled && /\<\/head\>/i.test(layout) ) { // placed in the HEAD
962
+ if ( isDeferModeEnabled && /\<\/head\>/i.test(layout) ) { // placed in the HEAD
943
963
  layout = layout.replace(/\<\/head\>/i, '\t{{ page.view.scripts }}\n\t</head>');
944
-
945
- } else { // placed in the BODY
964
+
965
+ } else { // placed in the BODY
946
966
  layout = layout.replace(/\<\/body\>/i, '\t{{ page.view.scripts }}\n</body>');
947
967
  }
948
968
  // ginaLoader cannot be deferred
@@ -951,20 +971,20 @@ function SuperController(options) {
951
971
  }
952
972
  }
953
973
  }
954
-
955
-
974
+
975
+
956
976
  layout = whisper(dic, layout, /\{{ ([a-zA-Z.]+) \}}/g );
957
977
  dic['page.content'] = layout;
958
978
  /**
959
979
  // special case for template without layout in debug mode - dev only
960
980
  if ( hasViews() && localOptions.debugMode && self.isCacheless() && !/\{\# Gina Toolbar \#\}/.test(layout) ) {
961
- try {
962
-
963
- layout = layout.replace(/<\/body>/i, plugin + '\n\t</body>');
981
+ try {
982
+
983
+ layout = layout.replace(/<\/body>/i, plugin + '\n\t</body>');
964
984
  layout = whisper(dic, layout, /\{{ ([a-zA-Z.]+) \}}/g );
965
985
  //swig.invalidateCache();
966
986
  layout = swig.compile(layout, mapping)(data);
967
-
987
+
968
988
 
969
989
  } catch (err) {
970
990
  filename = localOptions.template.html;
@@ -972,7 +992,7 @@ function SuperController(options) {
972
992
  self.throwError(local.res, 500, new Error('Compilation error encountered while trying to process template `'+ filename + '`\n'+(err.stack||err.message)));
973
993
  return;
974
994
  }
975
- }
995
+ }
976
996
  else if (hasViews() && localOptions.debugMode && self.isCacheless()) {
977
997
  try {
978
998
  //layout = whisper(dic, layout, /\{{ ([a-zA-Z.]+) \}}/g );
@@ -983,9 +1003,9 @@ function SuperController(options) {
983
1003
  self.throwError(local.res, 500, new Error('Compilation error encountered while trying to process template `'+ filename + '`\n'+(err.stack||err.message)));
984
1004
  return;
985
1005
  }
986
- }
987
- */
988
-
1006
+ }
1007
+ */
1008
+
989
1009
 
990
1010
  if ( !local.res.headersSent ) {
991
1011
  local.res.statusCode = ( typeof(localOptions.conf.server.coreConfiguration.statusCodes[data.page.data.status]) != 'undefined' ) ? data.page.data.status : 200; // by default
@@ -1004,62 +1024,63 @@ function SuperController(options) {
1004
1024
  }
1005
1025
 
1006
1026
  local.res.setHeader('content-type', localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding );
1007
-
1027
+
1008
1028
  try {
1009
-
1029
+
1010
1030
  // escape special chars
1011
1031
  var blacklistRe = new RegExp('[\<\>]', 'g');
1012
1032
  // DO NOT REPLACE IT BY JSON.clone() !!!!
1013
-
1033
+
1014
1034
  data.page.data = JSON.parse(JSON.stringify(data.page.data).replace(blacklistRe, '\$&'));
1015
-
1035
+
1016
1036
  } catch (err) {
1017
1037
  filename = localOptions.template.html;
1018
1038
  filename += ( typeof(data.page.view.namespace) != 'undefined' && data.page.view.namespace != '' && new RegExp('^' + data.page.view.namespace +'-').test(data.page.view.file) ) ? '/' + data.page.view.namespace + data.page.view.file.split(data.page.view.namespace +'-').join('/') + ( (data.page.view.ext != '') ? data.page.view.ext: '' ) : '/' + data.page.view.file+ ( (data.page.view.ext != '') ? data.page.view.ext: '' );
1019
1039
  self.throwError(local.res, 500, new Error('Controller::render(...) compilation error encountered while trying to process template `'+ filename + '`\n' + (err.stack||err.message||err) ));
1020
1040
  return;
1021
1041
  }
1022
-
1023
-
1042
+
1043
+
1024
1044
  // Only available for http/2.0 for now
1025
1045
  if ( !self.isXMLRequest() && /http\/2/.test(localOptions.conf.server.protocol) ) {
1026
1046
  try {
1027
- // TODO - button in toolbar to empty url assets cache
1047
+ // TODO - button in toolbar to empty url assets cache
1028
1048
  if ( /** self.isCacheless() ||*/ typeof(localOptions.template.assets) == 'undefined' || typeof(localOptions.template.assets[local.req.url]) == 'undefined' ) {
1029
1049
  // assets string -> object
1030
1050
  //assets = self.serverInstance.getAssets(localOptions.conf, layout.toString(), swig, data);
1031
1051
  assets = self.serverInstance.getAssets(localOptions.conf, layout, swig, data);
1032
1052
  localOptions.template.assets = JSON.parse(assets);
1033
1053
  }
1034
-
1054
+
1035
1055
  // only for toolbar - TODO hasToolbar()
1036
1056
  if (
1037
1057
  self.isCacheless() && hasViews() && !isWithoutLayout
1038
1058
  || hasViews() && localOptions.debugMode
1039
- || self.isCacheless() && hasViews() && self.isXMLRequest()
1040
- ) {
1041
- layout = layout.replace('{"assets":"${assets}"}', assets );
1059
+ || self.isCacheless() && hasViews() && self.isXMLRequest()
1060
+ ) {
1061
+ layout = layout.replace('{"assets":"${assets}"}', assets );
1042
1062
  }
1043
-
1063
+
1044
1064
  } catch (err) {
1045
1065
  self.throwError(local.res, 500, new Error('Controller::render(...) calling getAssets(...) \n' + (err.stack||err.message||err) ));
1046
1066
  return;
1047
1067
  }
1048
1068
  }
1049
-
1050
- // Last compilation before rendering
1051
- layout = swig.compile(layout, mapping)(data);
1052
-
1069
+
1070
+ // Last compilation before rendering
1071
+ layout = swig.compile(layout, mapping)(data);
1072
+
1053
1073
  if ( !local.res.headersSent ) {
1054
1074
  if ( local.options.isRenderingCustomError ) {
1055
1075
  local.options.isRenderingCustomError = false;
1056
1076
  }
1077
+
1057
1078
  local.res.end(layout);
1058
- }
1059
-
1079
+ }
1080
+
1060
1081
  console.info(local.req.method +' ['+local.res.statusCode +'] '+ local.req.url);
1061
-
1062
- } else if (typeof(local.next) != 'undefined') {
1082
+
1083
+ } else if (typeof(local.next) != 'undefined') {
1063
1084
  // local.next();
1064
1085
  return local.next();
1065
1086
  } else {
@@ -1075,7 +1096,7 @@ function SuperController(options) {
1075
1096
  return;
1076
1097
  }
1077
1098
  }
1078
-
1099
+
1079
1100
 
1080
1101
  this.isXMLRequest = function() {
1081
1102
  return local.options.isXMLRequest;
@@ -1102,21 +1123,21 @@ function SuperController(options) {
1102
1123
  return false
1103
1124
  }
1104
1125
  if ( self.isProcessingError ) {
1105
- return;
1126
+ return;
1106
1127
  }
1107
1128
 
1108
1129
  var request = local.req;
1109
1130
  var response = local.res;
1110
1131
  var next = local.next || null;
1111
1132
  // var stream = null;
1112
- // if ( /http\/2/.test(local.options.conf.server.protocol) ) {
1113
- // stream = response.stream;
1133
+ // if ( /http\/2/.test(local.options.conf.server.protocol) ) {
1134
+ // stream = response.stream;
1114
1135
  // }
1115
1136
 
1116
1137
  if (!jsonObj) {
1117
1138
  jsonObj = {}
1118
1139
  }
1119
-
1140
+
1120
1141
  try {
1121
1142
  // just in case
1122
1143
  if ( typeof(jsonObj) == 'string') {
@@ -1126,7 +1147,7 @@ function SuperController(options) {
1126
1147
  // if( typeof(local.options) != "undefined" && typeof(local.options.charset) != "undefined" ){
1127
1148
  // response.setHeader("charset", local.options.charset);
1128
1149
  // }
1129
-
1150
+
1130
1151
 
1131
1152
  //catching errors
1132
1153
  if (
@@ -1164,17 +1185,17 @@ function SuperController(options) {
1164
1185
  } else {
1165
1186
  len = data.length
1166
1187
  }
1167
-
1188
+
1168
1189
  if (!response.headersSent)
1169
1190
  response.setHeader("content-length", len);
1170
-
1171
-
1191
+
1192
+
1172
1193
  // if (stream && !stream.destroyed) {
1173
1194
  // //stream.respond(header);
1174
1195
  // stream.end(data);
1175
1196
  // } else {
1176
1197
  response.write(data);
1177
-
1198
+
1178
1199
  // required to close connection
1179
1200
  setTimeout(function () {
1180
1201
  response.end();
@@ -1184,17 +1205,17 @@ function SuperController(options) {
1184
1205
  // Ignoring warning
1185
1206
  //console.warn(err);
1186
1207
  }
1187
-
1208
+
1188
1209
  if ( next ) {
1189
1210
  next()
1190
1211
  }
1191
1212
  }, 200);
1192
-
1193
-
1194
-
1213
+
1214
+
1215
+
1195
1216
  return // force completion
1196
1217
  // }
1197
-
1218
+
1198
1219
 
1199
1220
  } else { // normal case
1200
1221
  response.end(JSON.stringify(jsonObj));
@@ -1207,9 +1228,9 @@ function SuperController(options) {
1207
1228
  }
1208
1229
  }
1209
1230
  if ( next ) {
1210
- next()
1231
+ return next()
1211
1232
  }
1212
-
1233
+
1213
1234
  return;
1214
1235
  }
1215
1236
  }
@@ -1308,7 +1329,7 @@ function SuperController(options) {
1308
1329
  * Get data
1309
1330
  *
1310
1331
  * @param {String} variable Data name to set
1311
- * @returns {Object | String} data Data object or String
1332
+ * @returns {Object | String} data Data object or String
1312
1333
  * */
1313
1334
  var get = function(variable) {
1314
1335
  return local.userData[variable]
@@ -1324,24 +1345,24 @@ function SuperController(options) {
1324
1345
  self.throwError(500, new Error('No views configuration found. Did you try to add views before using Controller::render(...) ? Try to run: gina view:add '+ options.conf.bundle +' @'+ options.conf.projectName));
1325
1346
  return;
1326
1347
  }
1327
-
1348
+
1328
1349
  var authority = ( typeof(local.req.headers['x-forwarded-proto']) != 'undefined' ) ? local.req.headers['x-forwarded-proto'] : local.options.conf.server.scheme;
1329
1350
  authority += '://'+ local.req.headers.host;
1330
1351
  var useWebroot = false;
1331
1352
  if ( !/^\/$/.test(local.options.conf.server.webroot) && local.options.conf.server.webroot.length > 0 && local.options.conf.hostname.replace(/\:\d+$/, '') == authority ) {
1332
1353
  useWebroot = true
1333
1354
  }
1334
-
1355
+
1335
1356
  var reURL = new RegExp('^'+ local.options.conf.server.webroot);
1336
1357
 
1337
1358
  var cssStr = '', jsStr = '';
1338
-
1359
+
1339
1360
  //Get css
1340
1361
  if( viewConf.stylesheets ) {
1341
1362
  cssStr = getNodeRes('css', viewConf.stylesheets, useWebroot, reURL)
1342
1363
  }
1343
1364
  //Get js
1344
- if( viewConf.javascripts ) {
1365
+ if( viewConf.javascripts ) {
1345
1366
  jsStr = getNodeRes('js', viewConf.javascripts, useWebroot, reURL)
1346
1367
  }
1347
1368
 
@@ -1362,7 +1383,7 @@ function SuperController(options) {
1362
1383
  * @private
1363
1384
  * */
1364
1385
  var getNodeRes = function(type, resArr, useWebroot, reURL) {
1365
-
1386
+
1366
1387
  var r = 0
1367
1388
  , rLen = resArr.length
1368
1389
  , obj = null
@@ -1370,7 +1391,7 @@ function SuperController(options) {
1370
1391
  ;
1371
1392
  switch(type){
1372
1393
  case 'css':
1373
- for (; r < rLen; ++r) {
1394
+ for (; r < rLen; ++r) {
1374
1395
  obj = resArr[r];
1375
1396
  if (useWebroot && !reURL.test(obj.url) ) {
1376
1397
  obj.url = local.options.conf.server.webroot + obj.url.substr(1);
@@ -1378,32 +1399,32 @@ function SuperController(options) {
1378
1399
  // TODO - add support for cdn
1379
1400
  if (!/\:\/\//.test(obj.url) ) {
1380
1401
  obj.url = local.options.conf.hostname + obj.url;
1381
- }
1382
-
1402
+ }
1403
+
1383
1404
  if (obj.media)
1384
- str += '\n\t\t<link href="'+ obj.url +'" media="'+ obj.media +'" rel="'+ obj.rel +'" type="'+ obj.type +'">';
1405
+ str += '\n\t\t<link href="'+ obj.url +'" media="'+ obj.media +'" rel="'+ obj.rel +'" type="'+ obj.type +'">';
1385
1406
  else
1386
- str += '\n\t\t<link href="'+ obj.url +'" rel="'+ obj.rel +'" type="'+ obj.type +'">';
1407
+ str += '\n\t\t<link href="'+ obj.url +'" rel="'+ obj.rel +'" type="'+ obj.type +'">';
1387
1408
  }
1388
-
1409
+
1389
1410
  return str;
1390
1411
  break;
1391
1412
 
1392
1413
  case 'js':
1393
1414
  var deferMode = (local.options.template.javascriptsDeferEnabled) ? ' defer' : '';
1394
-
1415
+
1395
1416
  for (; r < rLen; ++r) {
1396
1417
  obj = resArr[r];
1397
1418
  if (useWebroot && !reURL.test(obj.url) ) {
1398
1419
  obj.url = local.options.conf.server.webroot + obj.url.substr(1);
1399
1420
  }
1400
- // TODO - add support for cdn
1421
+ // TODO - add support for cdn
1401
1422
  if (!/\:\/\//.test(obj.url) ) {
1402
1423
  obj.url = local.options.conf.hostname + obj.url;
1403
1424
  }
1404
- str += '\n\t\t<script'+ deferMode +' type="'+ obj.type +'" src="'+ obj.url +'"></script>'
1425
+ str += '\n\t\t<script'+ deferMode +' type="'+ obj.type +'" src="'+ obj.url +'"></script>'
1405
1426
  }
1406
-
1427
+
1407
1428
  return str;
1408
1429
  break;
1409
1430
  }
@@ -1419,17 +1440,17 @@ function SuperController(options) {
1419
1440
  var getData = function() {
1420
1441
  return refToObj( local.userData )
1421
1442
  }
1422
-
1443
+
1423
1444
 
1424
1445
  var isValidURL = function(url){
1425
1446
  var re = /(http|ftp|https|sftp):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&amp;:\/~+#-]*[\w@?^=%&amp;\/~+#-])?/;
1426
1447
  return (re.test(url)) ? true : false
1427
1448
  }
1428
-
1449
+
1429
1450
  /**
1430
- * Set method - Override current method
1451
+ * Set method - Override current method
1431
1452
  * E.g.: in case of redirect, to force PUT to GET
1432
- *
1453
+ *
1433
1454
  * @param {string} requestMethod - GET, POST, PUT, DELETE
1434
1455
  */
1435
1456
  var localRequestMethod = null, localRequestMethodParams = null;
@@ -1438,75 +1459,75 @@ function SuperController(options) {
1438
1459
  if ( /http\/2/i.test(conf.server.protocolShort) ) {
1439
1460
  local.req.headers[':method'] = local.req.method.toUpperCase()
1440
1461
  }
1441
-
1462
+
1442
1463
  localRequestMethod = local.req.method = local.req.routing.method = requestMethod.toUpperCase();
1443
-
1464
+
1444
1465
  local.res.setHeader('access-control-allow-methods', localRequestMethod);
1445
-
1446
- return localRequestMethod;
1466
+
1467
+ return localRequestMethod;
1447
1468
  }
1448
-
1469
+
1449
1470
  this.getRequestMethod = function() {
1450
1471
  return localRequestMethod;
1451
1472
  }
1452
-
1473
+
1453
1474
  this.setRequestMethodParams = function(params) {
1454
1475
  localRequestMethodParams = local.req[local.req.method.toLowerCase()] = localRequestMethodParams = params
1455
1476
  }
1456
-
1477
+
1457
1478
  this.getRequestMethodParams = function() {
1458
- return (localRequestMethodParams) ? localRequestMethodParams : local.req[local.req.method.toLowerCase()]
1479
+ return (localRequestMethodParams) ? localRequestMethodParams : local.req[local.req.method.toLowerCase()]
1459
1480
  }
1460
-
1481
+
1461
1482
  /**
1462
1483
  * isStaticRoute
1463
1484
  * Trying to determine if url is a `statics` ressource
1464
- *
1485
+ *
1465
1486
  * @param {string} url
1466
1487
  * @param {string} method
1467
- *
1488
+ *
1468
1489
  * @returns {boolean} isStaticRoute
1469
1490
  */
1470
1491
  var isStaticRoute = function(url, method, bundle, env, conf) {
1471
-
1492
+
1472
1493
  if ( !/get/i.test(method) ) {
1473
1494
  return false
1474
1495
  }
1475
-
1496
+
1476
1497
  // priority to statics - this portion of code has been duplicated to Server.js
1477
-
1498
+
1478
1499
  var staticsArr = conf[bundle][env].publicResources;
1479
1500
  var staticProps = {
1480
1501
  firstLevel : '/' + url.split(/\//g)[1] + '/',
1481
1502
  // to be considered as a stativ content, url must content at least 2 caracters after last `.`: .js, .html are ok
1482
1503
  isStaticFilename : /(\.([A-Za-z0-9]+){2}|\/)$/.test(url)
1483
- };
1484
-
1504
+ };
1505
+
1485
1506
  // handle resources from public with webroot in url
1486
1507
  if ( staticProps.isStaticFilename && conf[bundle][env].server.webroot != '/' && staticProps.firstLevel == conf[bundle][env].server.webroot ) {
1487
1508
  var matchedFirstInUrl = url.replace(conf[bundle][env].server.webroot, '').match(/[A-Za-z0-9_-]+\/?/);
1488
1509
  if ( matchedFirstInUrl && matchedFirstInUrl.length > 0 ) {
1489
1510
  staticProps.firstLevel = conf[bundle][env].server.webroot + matchedFirstInUrl[0]
1490
- }
1511
+ }
1491
1512
  }
1492
-
1493
- if (
1494
- staticProps.isStaticFilename && staticsArr.indexOf(url) > -1
1495
- || staticProps.isStaticFilename && staticsArr.indexOf( url.replace(url.substr(url.lastIndexOf('/')+1), '') ) > -1
1513
+
1514
+ if (
1515
+ staticProps.isStaticFilename && staticsArr.indexOf(url) > -1
1516
+ || staticProps.isStaticFilename && staticsArr.indexOf( url.replace(url.substr(url.lastIndexOf('/')+1), '') ) > -1
1496
1517
  || staticProps.isStaticFilename && staticsArr.indexOf(staticProps.firstLevel) > -1
1497
1518
  ) {
1498
1519
  return true
1499
1520
  }
1500
-
1521
+
1501
1522
  return false;
1502
1523
  }
1503
1524
 
1504
1525
  /**
1505
1526
  * redirect
1506
1527
  *
1507
- * TODO - improve redirect based on `utils.routing`
1528
+ * TODO - improve redirect based on `lib.routing`
1508
1529
  * e.g.: self.redirect('project-get', { companyId: companyId, clientId: clientId, id: projectId }, true)
1509
- *
1530
+ *
1510
1531
  * How to avoid redirect inside popin context
1511
1532
  * N.B.: When you are in a popin context, add an `id` to your template tag so it can be ignored by the default PopinHandler
1512
1533
  * E.g.: id="delete-link" -> <a href="#" id="delete-link">delete</a>
@@ -1553,10 +1574,10 @@ function SuperController(options) {
1553
1574
  * `ignoreWebRoot` behaves the like set to `false` by default
1554
1575
  *
1555
1576
  * N.B.: Gina will tell browsers not to cache redirections if you are using `dev` environement
1556
- *
1577
+ *
1557
1578
  * Trobleshouting:
1558
1579
  * ---------------
1559
- *
1580
+ *
1560
1581
  * Redirecting to a popin from the controller while posting from a form
1561
1582
  * If this does not work, like doing a real redirect, this
1562
1583
  * only means that the ID you are using for the form might be
@@ -1567,7 +1588,7 @@ function SuperController(options) {
1567
1588
  * @param {object} [params] TODO
1568
1589
  *
1569
1590
  * @callback [ next ]
1570
- * */
1591
+ * */
1571
1592
  this.redirect = function(req, res, next) {
1572
1593
  var conf = self.getConfig();
1573
1594
  var bundle = conf.bundle;
@@ -1579,15 +1600,15 @@ function SuperController(options) {
1579
1600
  var ignoreWebRoot = null, isRelative = false;
1580
1601
  var originalUrl = null;
1581
1602
  var method = null;
1582
- var originalMethod = null;
1603
+ var originalMethod = null;
1583
1604
 
1584
1605
  if ( typeof(req) === 'string' ) {
1585
1606
 
1586
1607
  // if ( typeof(res) == 'undefined') {
1587
1608
  // // nothing to do
1588
1609
  // ignoreWebRoot = false
1589
- // } else
1590
- if (typeof(res) === 'string' || typeof(res) === 'number' || typeof(res) === 'boolean') {
1610
+ // } else
1611
+ if (typeof(res) === 'string' || typeof(res) === 'number' || typeof(res) === 'boolean') {
1591
1612
  if ( /true|1/.test(res) ) {
1592
1613
  ignoreWebRoot = true
1593
1614
  } else if ( /false|0/.test(res) ) {
@@ -1608,26 +1629,26 @@ function SuperController(options) {
1608
1629
  ignoreWebRoot = false;
1609
1630
  }
1610
1631
  }
1611
-
1632
+
1612
1633
  }
1613
1634
 
1614
1635
  if ( req.substr(0,1) === '/') { // is relative (not checking if the URI is defined in the routing.json)
1615
1636
  // if (wroot.substr(wroot.length-1,1) == '/') {
1616
1637
  // wroot = wroot.substr(wroot.length-1,1).replace('/', '')
1617
1638
  // }
1618
-
1639
+
1619
1640
  if ( /^\//.test(req) && !ignoreWebRoot )
1620
1641
  req = req.substr(1);
1621
-
1642
+
1622
1643
  rte = ( ignoreWebRoot != null && ignoreWebRoot ) ? req : wroot + req;
1623
1644
  // cleaning url in case of ?param=value
1624
- originalUrl = rte;
1645
+ originalUrl = rte;
1625
1646
  rte = rte.replace(/\?(.*)/, '');
1626
-
1647
+
1627
1648
  req = local.req;
1628
- originalMethod = ( typeof(req.originalMethod) != 'undefined') ? req.originalMethod : req.method;
1629
- console.debug('[ BUNDLE ][ '+ local.options.conf.bundle +' ][ Controller ] trying to get route: ', rte, bundle, req.method);
1630
- if ( !ignoreWebRoot || !isStaticRoute(rte, req.method, bundle, env, ctx.config.envConf) && !ignoreWebRoot ) {
1649
+ originalMethod = ( typeof(req.originalMethod) != 'undefined') ? req.originalMethod : req.method;
1650
+ console.debug('[ BUNDLE ][ '+ local.options.conf.bundle +' ][ Controller ] trying to get route: ', rte, bundle, req.method);
1651
+ if ( !ignoreWebRoot || !isStaticRoute(rte, req.method, bundle, env, ctx.config.envConf) && !ignoreWebRoot ) {
1631
1652
  req.routing = lib.routing.getRouteByUrl(rte, bundle, req.method, req);
1632
1653
  // try alternative method
1633
1654
  if (!req.routing) {
@@ -1637,7 +1658,7 @@ function SuperController(options) {
1637
1658
  method = req.method = 'GET'
1638
1659
  }
1639
1660
  }
1640
-
1661
+
1641
1662
  //route = route = req.routing.name;
1642
1663
  } else {
1643
1664
  req.routing = {
@@ -1646,59 +1667,59 @@ function SuperController(options) {
1646
1667
  }
1647
1668
  }
1648
1669
  }
1649
-
1670
+
1650
1671
  res = local.res;
1651
1672
  next = local.next;
1652
1673
  isRelative = true;
1653
-
1674
+
1654
1675
  req.routing.param.path = rte
1655
1676
  } else if ( isValidURL(req) ) { // might be an URL
1656
1677
  rte = req;
1657
- originalUrl = rte;
1678
+ originalUrl = rte;
1658
1679
  rte = rte.replace(/\?(.*)/, '');
1659
-
1680
+
1660
1681
  req = local.req;
1661
1682
  res = local.res;
1662
1683
  next = local.next;
1663
-
1684
+
1664
1685
  req.routing.param.url = rte
1665
1686
  } else { // is by default a route name
1666
-
1687
+
1667
1688
  if ( /\@/.test(req) ) {
1668
1689
  var rteArr = req.split(/\//);
1669
1690
  if ( typeof(rteArr[1]) != 'undefined' )
1670
1691
  env = rteArr[1];
1671
-
1692
+
1672
1693
  rte = route = rteArr[0];
1673
1694
  rteArr = rteArr[0].split(/\@/);
1674
-
1695
+
1675
1696
  bundle = rteArr[1];
1676
-
1697
+
1677
1698
  } else {
1678
1699
  rte = route = ( new RegExp('^/'+conf.bundle+'-$').test(req) ) ? req : wroot.match(/[^/]/g).join('') +'-'+ req;
1679
1700
  }
1680
-
1681
-
1701
+
1702
+
1682
1703
  req = local.req;
1683
1704
  res = local.res;
1684
1705
  next = local.next;
1685
-
1706
+
1686
1707
  req.routing.param.route = routing[rte]
1687
- }
1688
-
1708
+ }
1709
+
1689
1710
  } else {
1690
- route = req.routing.param.route;
1711
+ route = req.routing.param.route;
1691
1712
  }
1692
-
1713
+
1693
1714
  if ( !originalMethod ) {
1694
1715
  originalMethod = ( typeof(req.originalMethod) != 'undefined') ? req.originalMethod : req.method;
1695
1716
  }
1696
-
1697
- var path = originalUrl || req.routing.param.path || '';
1717
+
1718
+ var path = originalUrl || req.routing.param.path || '';
1698
1719
  var url = req.routing.param.url;
1699
- var code = req.routing.param.code || 301;
1720
+ var code = req.routing.param.code || 301;
1700
1721
 
1701
- var keepParams = req.routing.param['keep-params'] || false;
1722
+ var keepParams = req.routing.param['keep-params'] || false;
1702
1723
 
1703
1724
  var condition = true; //set by default for url @ path redirect
1704
1725
 
@@ -1710,20 +1731,20 @@ function SuperController(options) {
1710
1731
 
1711
1732
  var isProxyHost = ( typeof(local.req.headers.host) != 'undefined' && local.options.conf.server.scheme +'://'+ local.req.headers.host != local.options.conf.hostname || typeof(local.req.headers[':authority']) != 'undefined' && local.options.conf.server.scheme +'://'+ local.req.headers[':authority'] != local.options.conf.hostname ) ? true : false;
1712
1733
  var hostname = (isProxyHost) ? ctx.config.envConf[bundle][env].hostname.replace(/\:\d+$/, '') : ctx.config.envConf[bundle][env].hostname;
1713
-
1734
+
1714
1735
  // if ( !/\:\d+$/.test(req.headers.host) )
1715
1736
  // hostname = hostname.replace(/\:\d+$/, '');
1716
1737
 
1717
1738
  if (route) { // will go with route first
1718
-
1739
+
1719
1740
  if ( /\,/.test(routing[route].url) ) {
1720
1741
  var paths = routing[route].url.split(/\,/g);
1721
1742
  path = (ignoreWebRoot) ? paths[0].replace(wroot, '') : paths[0];
1722
1743
  } else {
1723
1744
  path = (ignoreWebRoot) ? routing[route].url.replace(wroot, '') : routing[route].url;
1724
1745
  }
1725
-
1726
- if (bundle != conf.bundle) {
1746
+
1747
+ if (bundle != conf.bundle) {
1727
1748
  path = hostname + path;
1728
1749
  }
1729
1750
  } else if (url && !path) {
@@ -1737,59 +1758,59 @@ function SuperController(options) {
1737
1758
  // nothing to do, just ignoring
1738
1759
  //} else {
1739
1760
  } else if ( !path && typeof(isRelative) == 'undefined' ) {
1740
-
1761
+
1741
1762
  path = hostname + path
1742
1763
  //path = local.req.headers.host + path
1743
1764
  }
1744
-
1745
-
1765
+
1766
+
1746
1767
 
1747
1768
  if (!local.res.headersSent) {
1748
-
1769
+
1749
1770
  // backing up oldParams
1750
1771
  var oldParams = local.req[originalMethod.toLowerCase()];
1751
- var requestParams = req[req.method.toLowerCase()] || {};
1772
+ var requestParams = req[req.method.toLowerCase()] || {};
1752
1773
  if ( typeof(requestParams) != 'undefined' && typeof(requestParams.error) != 'undefined' ) {
1753
1774
  var redirectError = requestParams.error;
1754
1775
  self.throwError(requestParams.error);
1755
1776
  return;
1756
1777
  }
1757
-
1758
- if (
1759
- !/GET/i.test(req.method)
1760
- ||
1761
- originalMethod && !/GET/i.test(originalMethod)
1762
- ) { // trying to redirect using the wrong method ?
1763
-
1778
+
1779
+ if (
1780
+ !/GET/i.test(req.method)
1781
+ ||
1782
+ originalMethod && !/GET/i.test(originalMethod)
1783
+ ) { // trying to redirect using the wrong method ?
1784
+
1764
1785
  console.warn(new Error('Your are trying to redirect using the wrong method: `'+ req.method+'`.\nThis can often occur while redirecting from a controller to another controller or from a bundle to another.\nA redirection is not permitted in this scenario.\nD\'ont panic :)\nSwitching request method to `GET` method instead.\n').message);
1765
1786
  method = local.req.method = self.setRequestMethod('GET', conf);
1766
- code = 303;
1787
+ code = 303;
1767
1788
  }
1768
-
1769
-
1789
+
1790
+
1770
1791
  // merging new & olds params
1771
1792
  requestParams = merge(requestParams, oldParams);
1772
1793
  // remove session to prevent reaching the 2000 chars limit
1773
1794
  // if you need the session, you need to find another way to retrieve while in the next route
1774
- if ( typeof(requestParams.session) != 'undefined' ) {
1795
+ if ( typeof(requestParams.session) != 'undefined' ) {
1775
1796
  delete requestParams.session;
1776
1797
  }
1777
- if ( typeof(requestParams) != 'undefined' && requestParams.count() > 0 ) {
1798
+ if ( typeof(requestParams) != 'undefined' && requestParams.count() > 0 ) {
1778
1799
  //if ( typeof(requestParams.error) != 'undefined' )
1779
-
1800
+
1780
1801
  var inheritedData = null;
1781
1802
  if ( /\?/.test(path) ) {
1782
- inheritedData = '&inheritedData='+ encodeURIComponent(JSON.stringify(requestParams));
1803
+ inheritedData = '&inheritedData='+ encodeURIComponent(JSON.stringify(requestParams));
1783
1804
  } else {
1784
- inheritedData = '?inheritedData='+ encodeURIComponent(JSON.stringify(requestParams));
1785
- }
1786
-
1805
+ inheritedData = '?inheritedData='+ encodeURIComponent(JSON.stringify(requestParams));
1806
+ }
1807
+
1787
1808
  if ( inheritedData.length > 2000 ) {
1788
1809
  var error = new ApiError('Controller::redirect(...) exceptions: `inheritedData` reached 2000 chars limit', 424);
1789
1810
  self.throwError(error);
1790
1811
  return;
1791
1812
  }
1792
-
1813
+
1793
1814
  // if redirecting from a xhrRequest
1794
1815
  if ( self.isXMLRequest() ) {
1795
1816
  // `requestParams` should be stored in the session to avoid passing datas in clear
@@ -1803,21 +1824,24 @@ function SuperController(options) {
1803
1824
  redirectObj.location += inheritedData;
1804
1825
  }
1805
1826
  }
1806
-
1827
+
1807
1828
  self.renderJSON(redirectObj);
1808
1829
  return;
1809
1830
  }
1810
-
1831
+
1811
1832
  path += inheritedData;
1812
- }
1813
-
1833
+ }
1834
+
1814
1835
  var ext = 'html';
1815
1836
  res.setHeader('content-type', local.options.conf.server.coreConfiguration.mime[ext]);
1816
-
1817
- if (
1818
- typeof(local.res._headers) != 'undefined'
1819
- && typeof(local.res._headers['access-control-allow-methods']) != 'undefined'
1820
- && local.res._headers['access-control-allow-methods'] != req.method
1837
+
1838
+ var resHeaderACAM = res.getHeader('access-control-allow-methods');
1839
+ if (
1840
+ // typeof(local.res._headers) != 'undefined'
1841
+ // && typeof(local.res._headers['access-control-allow-methods']) != 'undefined'
1842
+ // && local.res._headers['access-control-allow-methods'] != req.method
1843
+ typeof(resHeaderACAM) != 'undefined'
1844
+ && resHeaderACAM != req.method
1821
1845
  ||
1822
1846
  !new RegExp(req.method, 'i').test( res.getHeader('access-control-allow-methods') )
1823
1847
  ) {
@@ -1825,11 +1849,11 @@ function SuperController(options) {
1825
1849
  }
1826
1850
  //path += '?query='+ JSON.stringify(self.getRequestMethodParams());
1827
1851
  local.req[req.method.toLowerCase()] = self.getRequestMethodParams() || {};
1828
-
1852
+
1829
1853
  var headInfos = {
1830
- 'location': path
1831
- };
1832
-
1854
+ 'location': path
1855
+ };
1856
+
1833
1857
  if (self.isCacheless()) {
1834
1858
  res.writeHead(code, merge(headInfos, {
1835
1859
  'cache-control': 'no-cache, no-store, must-revalidate', // preventing browsers from using cache
@@ -1838,24 +1862,26 @@ function SuperController(options) {
1838
1862
  }))
1839
1863
  } else {
1840
1864
  res.writeHead(code, headInfos)
1841
- }
1842
- // in case of query from another bundle waiting for a response
1843
- var redirectObject = JSON.stringify({ status: code, headers: headInfos });
1844
- res.end(redirectObject);
1865
+ }
1866
+ // in case of query from another bundle waiting for a response
1867
+ var redirectObject = JSON.stringify({ status: code, headers: headInfos });
1868
+
1845
1869
  try {
1870
+ res.end(redirectObject);
1846
1871
  local.res.headersSent = true;// done for the render() method
1847
1872
  } catch(err){
1848
1873
  // ignoring the warning
1874
+ // console.warn(err.stack);
1849
1875
  }
1850
-
1876
+
1851
1877
  console.info(local.req.method.toUpperCase() +' ['+code+'] '+ path);
1852
-
1878
+
1853
1879
  if ( typeof(next) != 'undefined' )
1854
1880
  next();
1855
1881
  else
1856
1882
  return;
1857
1883
  }
1858
-
1884
+
1859
1885
  }
1860
1886
  }
1861
1887
 
@@ -1896,7 +1922,7 @@ function SuperController(options) {
1896
1922
  })
1897
1923
  }
1898
1924
  }
1899
-
1925
+
1900
1926
  this.getBundleStatus = function(req, res, next) {
1901
1927
  self.renderJSON({
1902
1928
  status: 200,
@@ -1904,8 +1930,8 @@ function SuperController(options) {
1904
1930
  message: 'I am alive !'
1905
1931
  });
1906
1932
  }
1907
-
1908
- this.checkBundleStatus = async function(bundle, cb) {
1933
+
1934
+ this.checkBundleStatus = async function(bundle, cb) {
1909
1935
  var opt = self.getConfig('app').proxy[bundle];
1910
1936
  var route = lib.routing.getRoute('bundle-status@'+bundle);
1911
1937
  opt.method = 'GET';
@@ -1915,29 +1941,35 @@ function SuperController(options) {
1915
1941
  .then( function onQueryResponse(_status) {
1916
1942
  response = _status
1917
1943
  });
1918
-
1944
+
1919
1945
  if (cb) {
1920
1946
  cb(error, response);
1921
1947
  } else {
1922
1948
  return response;
1923
1949
  }
1924
1950
  }
1925
-
1951
+
1926
1952
  /**
1927
1953
  * downloadFromURL
1928
1954
  * Download from an URL
1929
1955
  * - attachment/inline
1930
1956
  * OR
1931
- * - locally: `Controller.store(target, cb)` must be called to store on `onComplete` event
1932
- *
1957
+ * - locally: `Controller.store(target, cb)` must be called to store on `onComplete` event
1958
+ *
1959
+ * - Will trigger on frontend : Failed to load resource: Frame load interrupted
1960
+ * because there is no `res.end()`: whitch is normal, we want to stay on the referrer page
1961
+ *
1962
+ * - To avoid this, add to your download link the attribute `data-gina-link`
1963
+ * This will convert the regular HTTP Request to an XML Request
1964
+ *
1933
1965
  * @param {string} url - eg.: https://upload.wikimedia.org/wikipedia/fr/2/2f/Firefox_Old_Logo.png
1934
1966
  * @param {object} [options]
1935
- *
1936
- *
1967
+ *
1968
+ *
1937
1969
  * */
1938
1970
  this.downloadFromURL = function(url, options) {
1939
-
1940
- var defaultOptions = {
1971
+
1972
+ var defaultOptions = {
1941
1973
  // file name i you want to rename the file
1942
1974
  file: null,
1943
1975
  fileSize: null,
@@ -1947,7 +1979,7 @@ function SuperController(options) {
1947
1979
  contentDisposition: 'attachment',
1948
1980
  // content-type (https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Configuring_server_MIME_types)
1949
1981
  contentType: 'application/octet-stream',
1950
-
1982
+
1951
1983
  agent: false,
1952
1984
  // set to false to ignore certificate verification
1953
1985
  rejectUnauthorized: true,
@@ -1957,9 +1989,9 @@ function SuperController(options) {
1957
1989
  keepAlive: true,
1958
1990
  headers: {}
1959
1991
  };
1960
-
1992
+
1961
1993
  var opt = ( typeof(options) != 'undefined' ) ? merge(options, defaultOptions) : defaultOptions;
1962
-
1994
+
1963
1995
  var requestOptions = {};
1964
1996
  for (var o in opt) {
1965
1997
  if ( !/(toLocalDir|contentDisposition|contentType|file)/.test(o) )
@@ -1968,130 +2000,135 @@ function SuperController(options) {
1968
2000
 
1969
2001
  // defining protocol & scheme
1970
2002
  var protocol = null;
1971
- var scheme = null;
1972
-
2003
+ var scheme = null;
2004
+
1973
2005
  if ( /\:\/\//.test(url) ) {
1974
2006
  scheme = url.match(/^\w+\:/)[0];
1975
2007
  scheme = scheme.substr(0, scheme.length-1);
1976
-
2008
+
1977
2009
  if ( !/^http/.test(scheme) ) {
1978
2010
  self.throwError(local.res, 500, new Error('[ '+ scheme +' ] Scheme not supported. Ref.: `http` or `https` only'));
1979
2011
  return;
1980
2012
  }
1981
-
1982
-
1983
-
2013
+
2014
+
2015
+
1984
2016
  } else { // by default
1985
2017
  scheme = 'http';
1986
2018
  }
1987
-
2019
+
1988
2020
  requestOptions.scheme = scheme +':';
1989
-
2021
+
1990
2022
  //defining port
1991
2023
  var port = url.match(/\:\d+\//) || null;
1992
2024
  if ( port != null ) {
1993
2025
  port = port[0].substr(1, port[0].length-2);
1994
- requestOptions.port = ~~port;
2026
+ requestOptions.port = ~~port;
1995
2027
  }
1996
-
2028
+
1997
2029
  // defining hostname & path
1998
2030
  var parts = url.replace(new RegExp( scheme + '\:\/\/'), '').split(/\//g);
1999
2031
  requestOptions.host = parts[0].replace(/\:\d+/, '');
2000
2032
  requestOptions.path = '/' + parts.splice(1).join('/');
2001
-
2002
-
2033
+
2034
+
2003
2035
  // extension and mime
2004
- var filename = url.split(/\//g).pop();
2036
+ var filename = url.split(/\//g).pop();
2005
2037
  if (!filename) {
2006
2038
  self.throwError(local.res, 500, new Error('Filename not found in url: `'+ url +'`'));
2007
2039
  return;
2008
2040
  }
2009
-
2010
-
2041
+
2042
+
2011
2043
  if ( !/\.\w+$/.test(filename) ) {
2012
2044
  self.throwError(local.res, 500, new Error('[ '+ filename +' ] extension not found.'));
2013
2045
  return;
2014
2046
  }
2015
-
2016
-
2047
+
2048
+
2017
2049
  // filename renaming
2018
2050
  if (opt.file)
2019
2051
  filename = opt.file;
2020
-
2052
+
2021
2053
  if ( opt.contentDisposition == 'attachment') {
2022
2054
  opt.contentDisposition += '; filename=' + filename;
2023
2055
  }
2024
-
2056
+
2025
2057
  var ext = filename.match(/\.\w+$/)[0].substr(1)
2026
2058
  , contentType = null
2027
2059
  , tmp = _(GINA_TMPDIR +'/'+ filename, true)
2028
2060
  ;
2029
-
2061
+
2030
2062
  if ( typeof(local.options.conf.server.coreConfiguration.mime[ext]) != 'undefined' ) {
2031
2063
 
2032
2064
  contentType = (opt.contentType != defaultOptions.contentType) ? opt.contentType : local.options.conf.server.coreConfiguration.mime[ext];
2033
-
2065
+
2034
2066
  } else { // extension not supported
2035
2067
  self.throwError(local.res, 500, new Error('[ '+ ext +' ] Extension not supported. Ref.: gina/core mime.types'));
2036
2068
  return;
2037
2069
  }
2038
-
2070
+
2039
2071
  // defining responseType
2040
2072
  requestOptions.headers['content-type'] = contentType;
2041
2073
  requestOptions.headers['content-disposition'] = opt.contentDisposition;
2042
-
2074
+
2043
2075
  var browser = require(''+ scheme);
2044
2076
  //console.debug('requestOptions: \n', JSON.stringify(requestOptions, null, 4));
2045
-
2046
- browser.get(requestOptions, function(response) {
2047
-
2048
- local.res.setHeader('content-type', contentType + '; charset='+ local.options.conf.encoding);
2049
- local.res.setHeader('content-disposition', opt.contentDisposition);
2050
- if (opt.fileSize) {
2051
- local.res.setHeader('content-length', opt.fileSize);
2052
- }
2053
- //local.res.setHeader('content-length', opt.fileSize);
2054
- // local.res.setHeader('cache-control', 'must-revalidate');
2055
- // local.res.setHeader('pragma', 'must-revalidate');
2056
-
2057
- // response.on('end', function onResponsePipeEnd(){
2058
- // self.renderJSON({ url: url});
2059
- // //local.res.end( Buffer.from(data) );
2060
- // //local.res.headersSent = true;
2061
-
2062
- // // if ( typeof(local.next) != 'undefined')
2063
- // // local.next();
2064
- // // else
2065
- // // return;
2066
- // });
2067
-
2068
- response.pipe(local.res);
2069
- });
2070
-
2071
- return;
2072
2077
 
2078
+ browser
2079
+ .get(requestOptions, function(response) {
2080
+
2081
+ local.res.setHeader('content-type', contentType + '; charset='+ local.options.conf.encoding);
2082
+ local.res.setHeader('content-disposition', opt.contentDisposition);
2083
+ if (opt.fileSize) {
2084
+ local.res.setHeader('content-length', opt.fileSize);
2085
+ }
2086
+ //local.res.setHeader('content-length', opt.fileSize);
2087
+ // local.res.setHeader('cache-control', 'must-revalidate');
2088
+ // local.res.setHeader('pragma', 'must-revalidate');
2089
+
2090
+
2091
+ response.pipe(local.res);
2092
+ })
2093
+ .on('error', function onDownloadError(err) {
2094
+ self.throwError(local.res, 500, err);
2095
+ });
2096
+
2097
+
2098
+
2099
+ // Will trigger on frontend : Failed to load resource: Frame load interrupted
2100
+ // because there is no `res.end()`: whitch is normal, we want to stay on the referrer page
2101
+
2102
+ // To avoid this, add to your download link the attribute `data-gina-link`
2103
+ // This will convert the regular HTTP Request to an XML Request
2073
2104
  }
2074
2105
 
2075
-
2106
+
2076
2107
  /**
2077
2108
  * Download to targeted filename.ext - Will create target if new
2078
2109
  * Use `cb` callback or `onComplete` event
2079
2110
  *
2111
+ * - Will trigger on frontend : Failed to load resource: Frame load interrupted
2112
+ * because there is no `res.end()`: whitch is normal, we want to stay on the referrer page
2113
+ *
2114
+ * - To avoid this, add to your download link the attribute `data-gina-link`
2115
+ * This will convert the regular HTTP Request to an XML Request
2116
+ *
2080
2117
  * @param {string} filename
2081
2118
  * @param {object} options
2082
2119
  **/
2083
2120
  this.downloadFromLocal = function(filename) {
2084
-
2085
- var file = filename.split(/\//g).pop();
2121
+
2122
+ var file = filename.split(/\//g).pop();
2086
2123
  var ext = file.split(/\./g).pop()
2087
2124
  , contentType = null
2088
2125
  ;
2089
-
2126
+
2090
2127
  if ( typeof(local.options.conf.server.coreConfiguration.mime[ext]) != 'undefined' ) {
2091
2128
 
2092
2129
  contentType = local.options.conf.server.coreConfiguration.mime[ext];
2093
2130
  local.res.setHeader('content-type', contentType);
2094
- local.res.setHeader('content-disposition', 'attachment; filename=' + file);
2131
+ local.res.setHeader('content-disposition', 'attachment; filename=' + file);
2095
2132
 
2096
2133
  var filestream = fs.createReadStream(filename);
2097
2134
  filestream.pipe(local.res);
@@ -2099,7 +2136,7 @@ function SuperController(options) {
2099
2136
  } else { // extension not supported
2100
2137
  self.throwError(local.res, 500, new Error('[ '+ ext +' ] Extension not supported. Ref.: gina/core mime.types'));
2101
2138
  return;
2102
- }
2139
+ }
2103
2140
  }
2104
2141
 
2105
2142
 
@@ -2122,17 +2159,17 @@ function SuperController(options) {
2122
2159
  * */
2123
2160
  this.store = async function(target, files, cb) {
2124
2161
 
2125
-
2162
+
2126
2163
  var start = function(target, files, cb) {
2127
-
2164
+
2128
2165
  if (arguments.length == 2 && typeof(arguments[1]) == 'function' ) {
2129
2166
  var cb = arguments[1];
2130
2167
  }
2131
-
2168
+
2132
2169
  if ( typeof(files) == 'undefined' || typeof(files) == 'function' ) {
2133
2170
  files = local.req.files
2134
2171
  }
2135
-
2172
+
2136
2173
  var uploadedFiles = [];
2137
2174
 
2138
2175
  if ( typeof(files) == 'undefined' || files.count() == 0 ) {
@@ -2155,25 +2192,25 @@ function SuperController(options) {
2155
2192
  self.emit('uploaded', folder)
2156
2193
  }
2157
2194
  } else {
2158
- // files list
2159
- var fileName = null;
2195
+ // files list
2196
+ var fileName = null;
2160
2197
  for (var len = files.length; i < len; ++i ){
2161
-
2162
- fileName = files[i].filename || files[i].originalFilename
2163
-
2198
+
2199
+ fileName = files[i].filename || files[i].originalFilename
2200
+
2164
2201
  list[i] = {
2165
2202
  source: files[i].path,
2166
2203
  target: _(uploadDir.toString() + '/' + fileName)
2167
2204
  };
2168
-
2169
- uploadedFiles[i] = {
2205
+
2206
+ uploadedFiles[i] = {
2170
2207
  file : fileName,
2171
- filename : list[i].target,
2208
+ filename : list[i].target,
2172
2209
  size : files[i].size,
2173
2210
  type : files[i].type,
2174
2211
  encoding : files[i].encoding
2175
2212
  };
2176
-
2213
+
2177
2214
  }
2178
2215
 
2179
2216
  movefiles(0, local.res, list, function (err) {
@@ -2279,7 +2316,7 @@ function SuperController(options) {
2279
2316
  } while (cert.fingerprint256 !== lastprint256);
2280
2317
 
2281
2318
  }*/
2282
-
2319
+
2283
2320
  };
2284
2321
 
2285
2322
  this.query = function() { // options, data, callback
@@ -2293,7 +2330,7 @@ function SuperController(options) {
2293
2330
  data = arguments[arguments.length-1]
2294
2331
  }
2295
2332
  // preventing multiple call of self.query() when controller is rendering from another required controller
2296
- if (
2333
+ if (
2297
2334
  typeof(local.options) != 'undefined'
2298
2335
  && typeof(local.options.renderingStack) != 'undefined'
2299
2336
  && local.options.renderingStack.length > 1
@@ -2301,22 +2338,22 @@ function SuperController(options) {
2301
2338
  return false
2302
2339
  }
2303
2340
  self.isProcessingError = false; // by default
2304
-
2341
+
2305
2342
  var queryData = {}
2306
2343
  , defaultOptions = local.query.options
2307
2344
  , path = options.path
2308
- , browser = null
2345
+ , browser = null
2309
2346
  ;
2310
2347
 
2311
2348
  // options must be used as a copy in case of multiple calls of self.query(options, ...)
2312
2349
  options = merge(JSON.clone(options), defaultOptions);
2313
-
2350
+
2314
2351
  for (var o in options) {//cleaning
2315
2352
  if ( typeof(options[o]) == 'undefined' || options[o] == undefined) {
2316
2353
  delete options[o]
2317
2354
  }
2318
2355
  }
2319
-
2356
+
2320
2357
  if (self.isCacheless() || self.isLocalScope() ) {
2321
2358
  options.rejectUnauthorized = false;
2322
2359
  }
@@ -2329,16 +2366,7 @@ function SuperController(options) {
2329
2366
  self.emit('query#complete', err)
2330
2367
  }
2331
2368
 
2332
-
2333
2369
 
2334
- // if (arguments.length <3) {
2335
- // if ( typeof(data) == 'function') {
2336
- // var callback = data;
2337
- // var data = undefined;
2338
- // } else {
2339
- // callback = undefined;
2340
- // }
2341
- // }
2342
2370
  if ( typeof(data) != 'undefined' && data.count() > 0) {
2343
2371
 
2344
2372
  queryData = '?';
@@ -2362,7 +2390,7 @@ function SuperController(options) {
2362
2390
 
2363
2391
  queryData = queryData.substring(0, queryData.length-1);
2364
2392
  queryData = queryData.replace(/\s/g, '%20');
2365
-
2393
+
2366
2394
  options.path += queryData;
2367
2395
  }
2368
2396
 
@@ -2370,7 +2398,7 @@ function SuperController(options) {
2370
2398
  queryData = ''
2371
2399
  }
2372
2400
 
2373
-
2401
+
2374
2402
  // Internet Explorer override
2375
2403
  if ( local.req != null && /msie/i.test(local.req.headers['user-agent']) ) {
2376
2404
  options.headers['content-type'] = 'text/plain';
@@ -2389,7 +2417,7 @@ function SuperController(options) {
2389
2417
 
2390
2418
  //you need this, even when empty.
2391
2419
  options.headers['content-length'] = queryData.length;
2392
-
2420
+
2393
2421
  // adding gina headers
2394
2422
  if ( local.req != null && typeof(local.req.ginaHeaders) != 'undefined' ) {
2395
2423
  // gina form headers
@@ -2405,7 +2433,7 @@ function SuperController(options) {
2405
2433
  ;
2406
2434
  // cleanup options.path
2407
2435
  if (/\:\/\//.test(options.path)) {
2408
-
2436
+
2409
2437
  var hArr = options.path.split(/^(https|http)\:\/\//);
2410
2438
  var domain = hArr[1] +'://';
2411
2439
  var host = hArr[2].split(/\//)[0];
@@ -2417,72 +2445,84 @@ function SuperController(options) {
2417
2445
  .replace(options.host, '')
2418
2446
  .replace(':'+port, '');
2419
2447
  }
2420
-
2448
+
2421
2449
  // retrieve protocol & scheme: if empty, take the bundles protocol
2422
2450
  protocol = options.protocol || ctx.gina.config.envConf[ctx.bundle][ctx.env].server.protocol;// bundle servers's protocol by default
2423
2451
  protocol = protocol.match(/[.a-z 0-9]+/ig)[0];
2424
2452
  scheme = options.scheme || ctx.gina.config.envConf[ctx.bundle][ctx.env].server.scheme;// bundle servers's scheme by default
2425
2453
  scheme = scheme.match(/[a-z 0-9]+/ig)[0];
2426
-
2454
+ // retrieve credentials
2455
+ if ( typeof(options.ca) == 'undefined' || ! options.ca ) {
2456
+ options.ca = ctx.gina.config.envConf[ctx.bundle][ctx.env].server.credentials.ca;
2457
+ }
2458
+
2427
2459
  //retrieving dynamic host, hostname & port
2428
2460
  if ( /\@/.test(options.hostname) ) {
2429
-
2461
+
2430
2462
  var bundle = ( options.hostname.replace(/(.*)\:\/\//, '') ).split(/\@/)[0];
2431
-
2463
+
2432
2464
  // No shorcut possible because conf.hostname might differ from user inputs
2433
2465
  options.host = ctx.gina.config.envConf[bundle][ctx.env].host.replace(/(.*)\:\/\//, '').replace(/\:\d+/, '');
2434
2466
  options.hostname = ctx.gina.config.envConf[bundle][ctx.env].hostname;
2435
2467
  options.port = ctx.gina.config.envConf[bundle][ctx.env].server.port;
2436
-
2468
+
2437
2469
  options.protocol = ctx.gina.config.envConf[bundle][ctx.env].server.protocol;
2438
2470
  options.scheme = ctx.gina.config.envConf[bundle][ctx.env].server.scheme;
2471
+
2472
+ // retrieve credentials
2473
+ if ( typeof(options.ca) == 'undefined' || ! options.ca ) {
2474
+ options.ca = ctx.gina.config.envConf[bundle][ctx.env].server.credentials.ca;
2475
+ }
2476
+
2439
2477
  // might be != from the bundle requesting
2440
- //options.protocol = ctx.gina.config.envConf[bundle][ctx.env].content.settings.server.protocol || ctx.gina.config.envConf[bundle][ctx.env].server.protocol;
2441
- //options.scheme = ctx.gina.config.envConf[bundle][ctx.env].content.settings.server.scheme || ctx.gina.config.envConf[bundle][ctx.env].server.scheme;
2478
+ //options.protocol = ctx.gina.config.envConf[bundle][ctx.env].content.settings.server.protocol || ctx.gina.config.envConf[bundle][ctx.env].server.protocol;
2479
+ //options.scheme = ctx.gina.config.envConf[bundle][ctx.env].content.settings.server.scheme || ctx.gina.config.envConf[bundle][ctx.env].server.scheme;
2442
2480
  }
2443
-
2481
+
2444
2482
  if ( typeof(options.protocol) == 'undefined' ) {
2445
2483
  options.protocol = protocol
2446
2484
  }
2447
2485
  if ( typeof(options.scheme) == 'undefined' ) {
2448
2486
  options.scheme = scheme
2449
2487
  }
2450
-
2451
-
2488
+
2489
+
2490
+
2491
+
2452
2492
  // reformating scheme
2453
2493
  if( !/\:$/.test(options.scheme) )
2454
2494
  options.scheme += ':';
2455
-
2456
- try {
2457
- options.queryData = queryData;
2495
+
2496
+ try {
2497
+ options.queryData = queryData;
2458
2498
  var protocolVersion = ~~options.protocol.match(/\/(.*)$/)[1].replace(/\.\d+/, '');
2459
2499
  var httpLib = options.protocol.match(/^(.*)\//)[1] + ( (protocolVersion >= 2) ? protocolVersion : '' );
2460
2500
  if ( !/http2/.test(httpLib) && /https/.test(options.scheme) ) {
2461
2501
  httpLib += 's';
2462
2502
  }
2463
-
2464
- browser = require(''+ httpLib);
2465
-
2503
+
2504
+ browser = require(''+ httpLib);
2505
+
2466
2506
  if ( /http2/.test(httpLib) ) {
2467
2507
  return handleHTTP2ClientRequest(browser, options, callback);
2468
2508
  } else {
2469
- return handleHTTP1ClientRequest(browser, options, callback);
2470
- }
2471
-
2472
-
2509
+ return handleHTTP1ClientRequest(browser, options, callback);
2510
+ }
2511
+
2512
+
2473
2513
  } catch(err) {
2474
2514
  if (callback) {
2475
2515
  return callback(err)
2476
2516
  }
2477
2517
  self.emit('query#complete', err)
2478
2518
  }
2479
-
2519
+
2480
2520
  }
2481
-
2521
+
2482
2522
  var handleHTTP1ClientRequest = function(browser, options, callback) {
2483
-
2523
+
2484
2524
  var altOpt = JSON.clone(options);
2485
-
2525
+
2486
2526
  altOpt.protocol = options.scheme;
2487
2527
  altOpt.hostname = options.host;
2488
2528
  altOpt.port = options.port;
@@ -2492,24 +2532,24 @@ function SuperController(options) {
2492
2532
  } catch(err) {
2493
2533
  self.emit('query#complete', err);
2494
2534
  }
2495
-
2535
+
2496
2536
  } else {
2497
2537
  console.warn('[ CONTROLLER ][ HTTP/1.0#query ] options.encKey not found !');
2498
2538
  }
2499
-
2539
+
2500
2540
  if ( typeof(altOpt.encCert) != 'undefined' ) {
2501
2541
  try {
2502
2542
  altOpt.encCert = fs.readFileSync(options.encCert);
2503
2543
  } catch(err) {
2504
2544
  self.emit('query#complete', err);
2505
2545
  }
2506
-
2546
+
2507
2547
  } else {
2508
2548
  console.warn('[ CONTROLLER ][ HTTP/1.0#query ] options.encCert not found !');
2509
2549
  }
2510
-
2550
+
2511
2551
  altOpt.agent = new browser.Agent(altOpt);
2512
-
2552
+
2513
2553
  var req = browser.request(altOpt, function(res) {
2514
2554
 
2515
2555
  res.setEncoding('utf8');
@@ -2526,24 +2566,24 @@ function SuperController(options) {
2526
2566
  });
2527
2567
 
2528
2568
  res.on('end', function onEnd(err) {
2529
-
2530
-
2569
+
2570
+
2531
2571
  // exceptions filter
2532
2572
  if ( typeof(data) == 'string' && /^Unknown ALPN Protocol/.test(data) ) {
2533
2573
  err = {
2534
2574
  status: 500,
2535
2575
  error: new Error(data)
2536
2576
  };
2537
-
2577
+
2538
2578
  if ( typeof(callback) != 'undefined' ) {
2539
2579
  callback(err)
2540
2580
  } else {
2541
2581
  self.emit('query#complete', err)
2542
2582
  }
2543
-
2583
+
2544
2584
  return
2545
2585
  }
2546
-
2586
+
2547
2587
  //Only when needed.
2548
2588
  if ( typeof(callback) != 'undefined' ) {
2549
2589
  if ( typeof(data) == 'string' && /^(\{|%7B|\[{)|\[\]/.test(data) ) {
@@ -2573,7 +2613,7 @@ function SuperController(options) {
2573
2613
  exception.status = 500;
2574
2614
  self.throwError(exception);
2575
2615
  return;
2576
- }
2616
+ }
2577
2617
 
2578
2618
  } else {
2579
2619
  if ( typeof(data) == 'string' && /^(\{|%7B|\[{)|\[\]/.test(data) ) {
@@ -2600,14 +2640,14 @@ function SuperController(options) {
2600
2640
 
2601
2641
  //starting from from >0.10.15
2602
2642
  req.on('error', function onError(err) {
2603
-
2604
-
2643
+
2644
+
2605
2645
  if (
2606
- typeof(err.code) != 'undefined' && /ECONNREFUSED|ECONNRESET/.test(err.code)
2607
- || typeof(err.cause) != 'undefined' && typeof(err.cause.code) != 'undefined' && /ECONNREFUSED|ECONNRESET/.test(err.cause.code)
2646
+ typeof(err.code) != 'undefined' && /ECONNREFUSED|ECONNRESET/.test(err.code)
2647
+ || typeof(err.cause) != 'undefined' && typeof(err.cause.code) != 'undefined' && /ECONNREFUSED|ECONNRESET/.test(err.cause.code)
2608
2648
  ) {
2609
2649
 
2610
- var port = getContext('gina').ports[options.protocol][options.scheme.replace(/\:/, '')][ options.port ];//err.port || err.cause.port
2650
+ var port = getContext('gina').ports[options.protocol][options.scheme.replace(/\:/, '')][ options.port ];//err.port || err.cause.port
2611
2651
  if ( typeof(port) != 'undefined' ) {
2612
2652
  err.accessPoint = port;
2613
2653
  err.message = '`Controller::query()` could not connect to [ ' + err.accessPoint + ' ] using port '+options.port+'.\n';
@@ -2626,7 +2666,7 @@ function SuperController(options) {
2626
2666
  } else {
2627
2667
  var error = {
2628
2668
  status : 500,
2629
- error : err.stack || err.message
2669
+ error : err.stack || err.message
2630
2670
  };
2631
2671
 
2632
2672
  self.emit('query#complete', error)
@@ -2667,30 +2707,30 @@ function SuperController(options) {
2667
2707
  exception.status = 500;
2668
2708
  self.throwError(exception);
2669
2709
  return;
2670
- }
2710
+ }
2671
2711
  })
2672
2712
  }
2673
-
2713
+
2674
2714
  }
2675
2715
  }
2676
-
2716
+
2677
2717
  var handleHTTP2ClientRequest = function(browser, options, callback) {
2678
-
2679
- //cleanup
2718
+
2719
+ //cleanup
2680
2720
  options[':authority'] = options.hostname;
2681
-
2721
+
2682
2722
  delete options.host;
2683
-
2723
+
2684
2724
  if ( typeof(options[':path']) == 'undefined' ) {
2685
2725
  options[':path'] = options.path;
2686
2726
  delete options.path;
2687
- }
2727
+ }
2688
2728
  if ( typeof(options[':method']) == 'undefined' ) {
2689
2729
  options[':method'] = options.method.toUpperCase();
2690
2730
  delete options.method;
2691
2731
  }
2692
-
2693
- // only if binary !!
2732
+
2733
+ // only if binary !!
2694
2734
  // if ( typeof(options['content-length']) == 'undefined' ) {
2695
2735
  // options['content-length'] = options.headers['content-length'] ;
2696
2736
  // delete options.headers['content-length'];
@@ -2699,11 +2739,11 @@ function SuperController(options) {
2699
2739
  // options['content-type'] = options.headers['content-type'] ;
2700
2740
  // delete options.headers['content-type'];
2701
2741
  // }
2702
-
2742
+
2703
2743
  if ( typeof(options[':scheme']) == 'undefined' ) {
2704
2744
  options[':scheme'] = options.scheme ;
2705
2745
  }
2706
-
2746
+
2707
2747
  if ( typeof(options.ca) != 'undefined' ) {
2708
2748
  try {
2709
2749
  options.ca = fs.readFileSync(options.ca);
@@ -2713,58 +2753,58 @@ function SuperController(options) {
2713
2753
  } else {
2714
2754
  self.emit('query#complete', err);
2715
2755
  }
2716
-
2756
+
2717
2757
  return;
2718
2758
  }
2719
-
2759
+
2720
2760
  } else {
2721
2761
  console.warn('[ CONTROLLER ][ HTTP/2.0#query ] options.ca not found !');
2722
2762
  }
2723
-
2724
-
2763
+
2764
+
2725
2765
  var body = Buffer.from(options.queryData);
2726
- options.headers['content-length'] = body.length;
2766
+ options.headers['content-length'] = body.length;
2727
2767
  delete options.queryData;
2728
-
2729
-
2730
-
2731
- const client = browser.connect(options.hostname, options);
2732
-
2733
-
2768
+
2769
+
2770
+
2771
+ const client = browser.connect(options.hostname, options);
2772
+
2773
+
2734
2774
  const {
2735
2775
  HTTP2_HEADER_PROTOCOL,
2736
- HTTP2_HEADER_SCHEME,
2776
+ HTTP2_HEADER_SCHEME,
2737
2777
  HTTP2_HEADER_AUTHORITY,
2738
2778
  HTTP2_HEADER_PATH,
2739
2779
  HTTP2_HEADER_METHOD,
2740
2780
  HTTP2_HEADER_STATUS
2741
2781
  } = browser.constants;
2742
-
2743
-
2782
+
2783
+
2744
2784
  if ( typeof(local.req.headers['x-requested-with']) != 'undefined' ) {
2745
2785
  options.headers['x-requested-with'] = local.req.headers['x-requested-with']
2746
2786
  }
2747
-
2787
+
2748
2788
  if ( typeof(local.req.headers['access-control-allow-credentials']) != 'undefined' ) {
2749
2789
  options.headers['access-control-allow-credentials'] = local.req.headers['access-control-allow-credentials']
2750
2790
  }
2751
-
2791
+
2752
2792
  if ( typeof(local.req.headers['content-type']) != 'undefined' && local.req.headers['content-type'] != options.headers['content-type'] ) {
2753
2793
  options.headers['content-type'] = local.req.headers['content-type']
2754
2794
  }
2755
-
2756
- var headers = merge({
2795
+
2796
+ var headers = merge({
2757
2797
  [HTTP2_HEADER_METHOD]: options[':method'],
2758
- [HTTP2_HEADER_PATH]: options[':path']
2798
+ [HTTP2_HEADER_PATH]: options[':path']
2759
2799
  }, options.headers);
2760
-
2800
+
2761
2801
  // merging with user options
2762
2802
  for (var o in options) {
2763
2803
  if (!/^\:/.test(o) && !/headers/.test(o) && typeof(headers[o]) == 'undefined' ) {
2764
2804
  headers[o] = options[o]
2765
2805
  }
2766
2806
  }
2767
-
2807
+
2768
2808
  /**
2769
2809
  * sessionOptions
2770
2810
  * endStream <boolean> true if the Http2Stream writable side should be closed initially, such as when sending a GET request that should not expect a payload body.
@@ -2778,55 +2818,55 @@ function SuperController(options) {
2778
2818
  endStream = false;
2779
2819
  sessionOptions.endStream = endStream;
2780
2820
  }
2781
-
2782
-
2821
+
2822
+
2783
2823
  client.on('error', (error) => {
2784
-
2824
+
2785
2825
  console.error( '`'+ options[':path']+ '` : '+ error.stack||error.message);
2786
- if (
2787
- typeof(error.cause) != 'undefined' && typeof(error.cause.code) != 'undefined' && /ECONNREFUSED|ECONNRESET/.test(error.cause.code)
2788
- || /ECONNREFUSED|ECONNRESET/.test(error.code)
2826
+ if (
2827
+ typeof(error.cause) != 'undefined' && typeof(error.cause.code) != 'undefined' && /ECONNREFUSED|ECONNRESET/.test(error.cause.code)
2828
+ || /ECONNREFUSED|ECONNRESET/.test(error.code)
2789
2829
  ) {
2790
-
2830
+
2791
2831
  var port = getContext('gina').ports[options.protocol][options.scheme.replace(/\:/, '')][ options.port ];
2792
2832
  if ( typeof(port) != 'undefined' ) {
2793
2833
  error.accessPoint = port;
2794
2834
  error.message = 'Could not connect to [ ' + error.accessPoint + ' ].\nThe `'+port.split(/\@/)[0]+'` bundle is offline or unreachable.\n';
2795
- }
2835
+ }
2796
2836
  }
2797
2837
  self.throwError(error);
2798
2838
  return;
2799
2839
  });
2800
-
2840
+
2801
2841
  client.on('connect', () => {
2802
-
2842
+
2803
2843
  var req = client.request( headers, sessionOptions );
2804
-
2805
-
2806
- // req.on('response', function onQueryResponse(headers, flags) {
2844
+
2845
+
2846
+ // req.on('response', function onQueryResponse(headers, flags) {
2807
2847
  // for (const name in headers) {
2808
2848
  // console.debug(`${name}: ${headers[name]}`);
2809
2849
  // }
2810
2850
  // });
2811
-
2851
+
2812
2852
  req.setEncoding('utf8');
2813
2853
  var data = '';
2814
- req.on('data', function onQueryDataChunk(chunk) {
2815
- data += chunk;
2854
+ req.on('data', function onQueryDataChunk(chunk) {
2855
+ data += chunk;
2816
2856
  });
2817
-
2857
+
2818
2858
  req.on('error', function onQueryError(error) {
2819
2859
 
2820
- if (
2821
- typeof(error.cause) != 'undefined' && typeof(error.cause.code) != 'undefined' && /ECONNREFUSED|ECONNRESET/.test(error.cause.code)
2822
- || /ECONNREFUSED|ECONNRESET/.test(error.code)
2860
+ if (
2861
+ typeof(error.cause) != 'undefined' && typeof(error.cause.code) != 'undefined' && /ECONNREFUSED|ECONNRESET/.test(error.cause.code)
2862
+ || /ECONNREFUSED|ECONNRESET/.test(error.code)
2823
2863
  ) {
2824
-
2864
+
2825
2865
  var port = getContext('gina').ports[options.protocol][options.scheme.replace(/\:/, '')][ options.port ];
2826
2866
  if ( typeof(port) != 'undefined' ) {
2827
2867
  error.accessPoint = port;
2828
2868
  error.message = 'Could not connect to [ ' + error.accessPoint + ' ].\n' + error.message;
2829
- }
2869
+ }
2830
2870
  }
2831
2871
 
2832
2872
 
@@ -2834,7 +2874,7 @@ function SuperController(options) {
2834
2874
  // you can get here if :
2835
2875
  // - you are trying to query using: `enctype="multipart/form-data"`
2836
2876
  // - server responded with an error
2837
- if ( typeof(callback) != 'undefined' ) {
2877
+ if ( typeof(callback) != 'undefined' ) {
2838
2878
  callback(error);
2839
2879
  } else {
2840
2880
  error = {
@@ -2844,28 +2884,28 @@ function SuperController(options) {
2844
2884
 
2845
2885
  self.emit('query#complete', error)
2846
2886
  }
2847
-
2887
+
2848
2888
  return;
2849
2889
  });
2850
-
2851
- req.on('end', function onEnd() {
2852
-
2890
+
2891
+ req.on('end', function onEnd() {
2892
+
2853
2893
  // exceptions filter
2854
2894
  if ( typeof(data) == 'string' && /^Unknown ALPN Protocol/.test(data) ) {
2855
2895
  var err = {
2856
2896
  status: 500,
2857
2897
  error: new Error(data)
2858
2898
  };
2859
-
2899
+
2860
2900
  if ( typeof(callback) != 'undefined' ) {
2861
2901
  callback(err)
2862
2902
  } else {
2863
2903
  self.emit('query#complete', err)
2864
2904
  }
2865
-
2905
+
2866
2906
  return
2867
2907
  }
2868
-
2908
+
2869
2909
  //Only when needed.
2870
2910
  if ( typeof(callback) != 'undefined' ) {
2871
2911
  if ( typeof(data) == 'string' && /^(\{|%7B|\[{)|\[\]/.test(data) ) {
@@ -2896,24 +2936,24 @@ function SuperController(options) {
2896
2936
  if ( data.status && /^3/.test(data.status) && typeof(data.headers) != 'undefined' ) {
2897
2937
  local.res.writeHead(data.status, data.headers);
2898
2938
  return local.res.end();
2899
- }
2900
-
2939
+ }
2940
+
2901
2941
  if ( data.status && !/^2/.test(data.status) && typeof(local.options.conf.server.coreConfiguration.statusCodes[data.status]) != 'undefined' ) {
2902
2942
  if ( /^5/.test(data.status) ) {
2903
- return callback(data)
2943
+ return callback(data)
2904
2944
  } else {
2905
2945
  self.throwError(data);
2906
2946
  return;
2907
- }
2947
+ }
2908
2948
  } else {
2909
2949
  // required when control is used in an halted state
2910
2950
  // Ref.: resumeRequest()
2911
2951
  if ( self && self.isHaltedRequest() && typeof(local.onHaltedRequestResumed) != 'undefined' ) {
2912
2952
  local.onHaltedRequestResumed(false);
2913
2953
  }
2914
- return callback( false, data )
2954
+ return callback( false, data )
2915
2955
  }
2916
-
2956
+
2917
2957
  } catch (e) {
2918
2958
  var infos = local.options, controllerName = infos.controller.substr(infos.controller.lastIndexOf('/'));
2919
2959
  var msg = 'Controller Query Exception while catching back.\nBundle: '+ infos.bundle +'\nController File: /controllers'+ controllerName +'\nControl: this.'+ infos.control +'(...)\n\r' + e.stack;
@@ -2921,8 +2961,8 @@ function SuperController(options) {
2921
2961
  exception.status = 500;
2922
2962
  self.throwError(exception);
2923
2963
  return;
2924
- }
2925
-
2964
+ }
2965
+
2926
2966
  } else {
2927
2967
  if ( typeof(data) == 'string' && /^(\{|%7B|\[{)|\[\]/.test(data) ) {
2928
2968
  try {
@@ -2935,13 +2975,13 @@ function SuperController(options) {
2935
2975
  self.emit('query#complete', data)
2936
2976
  }
2937
2977
  }
2938
-
2978
+
2939
2979
  // intercepting fallback redirect
2940
2980
  if ( data.status && /^3/.test(data.status) && typeof(data.headers) != 'undefined' ) {
2941
2981
  self.removeAllListeners(['query#complete']);
2942
2982
  local.res.writeHead(data.status, data.headers);
2943
2983
  return local.res.end();
2944
- }
2984
+ }
2945
2985
 
2946
2986
  if ( data.status && !/^2/.test(data.status) && typeof(local.options.conf.server.coreConfiguration.statusCodes[data.status]) != 'undefined' ) {
2947
2987
  self.emit('query#complete', data)
@@ -2953,22 +2993,22 @@ function SuperController(options) {
2953
2993
  }
2954
2994
  self.emit('query#complete', false, data)
2955
2995
  }
2956
- }
2957
-
2996
+ }
2997
+
2958
2998
  client.close();
2959
2999
  });
2960
-
3000
+
2961
3001
  if (!endStream) {
2962
3002
  req.end(body);
2963
3003
  }
2964
3004
  });
2965
-
2966
-
3005
+
3006
+
2967
3007
  return {
2968
3008
  onComplete : function(cb) {
2969
-
3009
+
2970
3010
  self.once('query#complete', function(err, data){
2971
-
3011
+
2972
3012
  if ( typeof(data) == 'string' && /^(\{|%7B|\[{)|\[\]/.test(data) ) {
2973
3013
  try {
2974
3014
  data = JSON.parse(data)
@@ -2979,7 +3019,7 @@ function SuperController(options) {
2979
3019
  }
2980
3020
  }
2981
3021
  }
2982
-
3022
+
2983
3023
  try {
2984
3024
  if ( data.status && !/^2/.test(data.status) && typeof(local.options.conf.server.coreConfiguration.statusCodes[data.status]) != 'undefined') {
2985
3025
  cb(data)
@@ -2989,7 +3029,7 @@ function SuperController(options) {
2989
3029
  if ( self.isHaltedRequest() && typeof(local.onHaltedRequestResumed) != 'undefined' ) {
2990
3030
  local.onHaltedRequestResumed(err);
2991
3031
  }
2992
-
3032
+
2993
3033
  cb(err, data)
2994
3034
  }
2995
3035
  } catch (e) {
@@ -2999,7 +3039,7 @@ function SuperController(options) {
2999
3039
  exception.status = 500;
3000
3040
  self.throwError(exception);
3001
3041
  return;
3002
- }
3042
+ }
3003
3043
  })
3004
3044
  }
3005
3045
  }
@@ -3066,8 +3106,8 @@ function SuperController(options) {
3066
3106
  }
3067
3107
 
3068
3108
  req.getParam = function(name) {
3069
-
3070
- var param = null;
3109
+
3110
+ var param = null;
3071
3111
  switch( req.method.toLowerCase() ) {
3072
3112
  case 'get':
3073
3113
  param = req.get[name];
@@ -3089,24 +3129,24 @@ function SuperController(options) {
3089
3129
  return param
3090
3130
  }
3091
3131
  }
3092
-
3132
+
3093
3133
  /**
3094
- * Forward request
3134
+ * Forward request
3095
3135
  * Allowing x-bundle forward
3096
3136
  * Attention: this is a work in progres, do not use it yet
3097
- *
3098
- * @param {object} req
3099
- * @param {object} res
3100
- * @param {callback} next
3101
- * @returns
3137
+ *
3138
+ * @param {object} req
3139
+ * @param {object} res
3140
+ * @param {callback} next
3141
+ * @returns
3102
3142
  */
3103
3143
  this.forward = function(req, res, next) {
3104
3144
  var route = req.routing;
3105
3145
  if ( typeof(route.param.url) == 'undefined' || /^(null|\s*)$/.test(route.param.url) ) {
3106
3146
  self.throwError( new Error('`route.param.url` must be defiend in your route: `'+ route.rule +'`') );
3107
3147
  return;
3108
- }
3109
-
3148
+ }
3149
+
3110
3150
  var param = {};
3111
3151
  for (let p in route.param) {
3112
3152
  if ( /^(url|urlIndex|control|file|title|bundle|project|hostname|port|path|method)$/.test(p) ) {
@@ -3138,14 +3178,14 @@ function SuperController(options) {
3138
3178
  port = route.param.port;
3139
3179
  path = route.param.port;
3140
3180
  }
3141
-
3181
+
3142
3182
  var method = null;
3143
3183
  if ( typeof(route.param.method) != 'undefined' ) {
3144
3184
  method = route.param.method.toLowerCase();
3145
3185
  } else {
3146
3186
  method = req.method.toLowerCase();
3147
3187
  }
3148
-
3188
+
3149
3189
  var opt = {
3150
3190
  ca: ca,
3151
3191
  hostname: hostname,
@@ -3156,7 +3196,7 @@ function SuperController(options) {
3156
3196
  if (self.isCacheless() || self.isLocalScope() ) {
3157
3197
  opt.rejectUnauthorized = false;
3158
3198
  }
3159
-
3199
+
3160
3200
  var obj = req[ req.method.toLowerCase() ];
3161
3201
  // if ( req.files != 'undefined' ) {
3162
3202
  // obj.files = req.files;
@@ -3166,17 +3206,17 @@ function SuperController(options) {
3166
3206
  self.throwError(err);
3167
3207
  return;
3168
3208
  }
3169
-
3209
+
3170
3210
  // TODO - filter : redirect & location
3171
-
3172
- // if ( self.isXMLRequest() || !hasViews() || !local.options.isUsingTemplate && !hasViews() || hasViews() && !local.options.isUsingTemplate ) {
3211
+
3212
+ // if ( self.isXMLRequest() || !hasViews() || !local.options.isUsingTemplate && !hasViews() || hasViews() && !local.options.isUsingTemplate ) {
3173
3213
  self.renderJSON(result)
3174
3214
  // } else {
3175
3215
  // self.render(result)
3176
- // }
3216
+ // }
3177
3217
  });
3178
3218
  }
3179
-
3219
+
3180
3220
 
3181
3221
  /**
3182
3222
  * Get config
@@ -3206,6 +3246,7 @@ function SuperController(options) {
3206
3246
 
3207
3247
  /**
3208
3248
  * Get locales
3249
+ * Will take only supported lang
3209
3250
  *
3210
3251
  * @param {string} [shortCountryCode] - e.g. EN
3211
3252
  *
@@ -3231,29 +3272,27 @@ function SuperController(options) {
3231
3272
  /**
3232
3273
  * Get countries list
3233
3274
  *
3234
- * @param {string} [code] - e.g.: short, long, fifa, m49
3275
+ * @param {string} [code] - e.g.: officialStateName, isoShort, isoLong, continent, capital, currency.name
3235
3276
  *
3236
3277
  * @returns {object} countries - countries code & value list
3237
3278
  * */
3238
3279
  var getCountries = function (code) {
3239
- var list = {}, cde = 'short', name = null;
3280
+ var list = [], cde = 'countryName';
3240
3281
 
3241
3282
  if ( typeof(code) != 'undefined' && typeof(userLocales[0][code]) == 'string' ) {
3242
3283
  cde = code
3243
- } else if ( typeof(code) != 'undefined' ) (
3284
+ } else if ( typeof(code) != 'undefined' ) {
3244
3285
  console.warn('`'+ code +'` not supported : sticking with `short` code')
3245
- )
3246
-
3247
-
3248
- for ( var i = 0, len = userLocales.length; i< len; ++i ) {
3249
-
3250
- if (userLocales[i][cde]) {
3286
+ }
3251
3287
 
3252
- name = userLocales[i].officialName.short || userLocales[i].full;
3253
3288
 
3254
- if ( name )
3255
- list[ userLocales[i][cde] ] = name;
3256
- }
3289
+ for ( let i = 0, len = userLocales.length; i< len; ++i ) {
3290
+ list[ i ] = {
3291
+ isoShort: userLocales[i].isoShort,
3292
+ isoLong: userLocales[i].isoLong,
3293
+ countryName: userLocales[i].countryName,
3294
+ officialStateName: userLocales[i].officialStateName
3295
+ };
3257
3296
  }
3258
3297
 
3259
3298
  return list
@@ -3261,6 +3300,7 @@ function SuperController(options) {
3261
3300
 
3262
3301
  return {
3263
3302
  'getCountries': getCountries
3303
+ // TODO - getCurrencies()
3264
3304
  }
3265
3305
  }
3266
3306
 
@@ -3297,8 +3337,8 @@ function SuperController(options) {
3297
3337
  } else {
3298
3338
  rules = JSON.clone(local.options.conf.content.forms).rules[form.id] || null;
3299
3339
  }
3300
-
3301
- if (!rules) {
3340
+
3341
+ if (!rules) {
3302
3342
  rules = {};
3303
3343
  console.warn('[CONTROLLER]['+ local.options.conf.bundle +'][Backend validation] did not find matching rules for form.id `'+ form.id +'` for `'+ bundle+' bundle`. Do not Panic if you did not defined any.')
3304
3344
  }
@@ -3307,40 +3347,40 @@ function SuperController(options) {
3307
3347
  return;
3308
3348
  }
3309
3349
  }
3310
-
3350
+
3311
3351
  return rules;
3312
3352
  }
3313
-
3353
+
3314
3354
  this.push = function(payload) {
3315
-
3355
+
3316
3356
  var req = local.req, res = local.res;
3317
3357
  var method = req.method.toLowerCase();
3318
3358
  // if no session defined, will push to all active clients
3319
3359
  var sessionId = ( typeof(req[method].sessionID) != 'undefined' ) ? req[method].sessionID : null;
3320
-
3360
+
3321
3361
  // resume current session
3322
-
3323
- if (!payload) {
3324
- payload = null;
3362
+
3363
+ if (!payload) {
3364
+ payload = null;
3325
3365
  if ( typeof(req[method]) != 'undefined' && typeof(req[method].payload) != 'undefined' ) {
3326
3366
  if ( typeof(payload) == 'string' ) {
3327
3367
  payload = decodeURIComponent(req[method].payload)
3328
3368
  } else {
3329
3369
  payload = JSON.stringify(req[method].payload)
3330
- }
3370
+ }
3331
3371
  }
3332
3372
  } else if ( typeof(payload) == 'object' ) {
3333
3373
  payload = JSON.stringify(payload)
3334
- }
3335
-
3374
+ }
3375
+
3336
3376
  try {
3337
3377
  var clients = null;
3338
3378
  if (sessionId) {
3339
3379
  clients = self.serverInstance.eio.getClientsBySessionId(sessionId);
3340
3380
  if (clients)
3341
3381
  clients.send(payload);
3342
- }
3343
-
3382
+ }
3383
+
3344
3384
  // send to all clients if no specific sessionId defined
3345
3385
  if (!sessionId) {
3346
3386
  clients = self.serverInstance.eio.clients;
@@ -3348,14 +3388,14 @@ function SuperController(options) {
3348
3388
  clients[id].send(payload)
3349
3389
  }
3350
3390
  }
3351
-
3391
+
3352
3392
  res.end();
3353
3393
  } catch(err) {
3354
3394
  self.throwError(err);
3355
3395
  return;
3356
- }
3396
+ }
3357
3397
  }
3358
-
3398
+
3359
3399
  var getSession = function() {
3360
3400
  var session = null;
3361
3401
  if ( typeof(local.req.session) != 'undefined') {
@@ -3365,10 +3405,10 @@ function SuperController(options) {
3365
3405
  if (!session && typeof(local.req.session) != 'undefined' && typeof(local.req.session.user) != 'undefined') {
3366
3406
  session = local.req.session.user;
3367
3407
  }
3368
-
3408
+
3369
3409
  return session;
3370
3410
  }
3371
-
3411
+
3372
3412
  this.isHaltedRequest = function(session) {
3373
3413
  // trying to retrieve session since it is optional
3374
3414
  if ( typeof(session) == 'undefined' ) {
@@ -3381,24 +3421,24 @@ function SuperController(options) {
3381
3421
  // session = local.req.session.user;
3382
3422
  // }
3383
3423
  if (
3384
- !session
3385
- ||
3424
+ !session
3425
+ ||
3386
3426
  typeof(session) != 'undefined'
3387
3427
  && typeof(session.haltedRequest) == 'undefined'
3388
3428
  ) {
3389
3429
  return false;
3390
3430
  }
3391
3431
  }
3392
-
3432
+
3393
3433
  return (typeof(session.haltedRequest) != 'undefined' ) ? true : false;
3394
3434
  }
3395
-
3396
-
3435
+
3436
+
3397
3437
  local.haltedRequestUrlResumed = false;
3398
-
3438
+
3399
3439
  this.pauseRequest = function(data, requestStorage) {
3400
-
3401
-
3440
+
3441
+
3402
3442
  // saving halted request
3403
3443
  var req = local.req
3404
3444
  , res = local.res
@@ -3410,22 +3450,22 @@ function SuperController(options) {
3410
3450
  data : JSON.clone(data)
3411
3451
  }
3412
3452
  ;
3413
-
3453
+
3414
3454
  if (
3415
3455
  typeof(requestStorage) == 'undefined'
3416
3456
  && typeof(req.session) != 'undefined'
3417
3457
  ) {
3418
3458
  requestStorage = req.session;
3419
3459
  }
3420
-
3460
+
3421
3461
  if (
3422
- typeof(requestStorage) == 'undefined'
3462
+ typeof(requestStorage) == 'undefined'
3423
3463
  ) {
3424
3464
  var error = new ApiError('`requestStorage` is required', 424);
3425
3465
  self.throwError(error);
3426
3466
  return;
3427
3467
  }
3428
-
3468
+
3429
3469
  var requestParams = {}, i = 0;
3430
3470
  for (var p in req.params) {
3431
3471
  if (i > 0) {
@@ -3436,13 +3476,13 @@ function SuperController(options) {
3436
3476
  if (requestParams.count() > 0) {
3437
3477
  haltedRequest.params = requestParams;
3438
3478
  }
3439
-
3479
+
3440
3480
  requestStorage.haltedRequest = haltedRequest;
3441
-
3481
+
3442
3482
  return requestStorage;
3443
3483
  }
3444
-
3445
-
3484
+
3485
+
3446
3486
  /**
3447
3487
  * resumeRequest
3448
3488
  * Used to resume an halted request
@@ -3450,35 +3490,35 @@ function SuperController(options) {
3450
3490
  * - a middleware attached `haltedRequest` to userSession
3451
3491
  * OR
3452
3492
  * - a persistant object where `haltedRequest` is attached
3453
- *
3454
- * @param {object} req
3455
- * @param {object} res
3493
+ *
3494
+ * @param {object} req
3495
+ * @param {object} res
3456
3496
  * @param {callback|null} next
3457
3497
  * @param {object} [requestStorage] - Will try to use sessionStorage if not passed
3458
3498
  */
3459
3499
  this.resumeRequest = function(requestStorage) {
3460
-
3500
+
3461
3501
  if (local.haltedRequestUrlResumed)
3462
3502
  return;
3463
-
3503
+
3464
3504
  var haltedRequest = null
3465
3505
  , req = local.req
3466
3506
  , res = local.res
3467
3507
  , next = local.next
3468
3508
  ;
3469
-
3509
+
3470
3510
  if (
3471
3511
  typeof(requestStorage) == 'undefined'
3472
3512
  && typeof(req.session) != 'undefined'
3473
3513
  ) {
3474
3514
  requestStorage = req.session;
3475
3515
  }
3476
-
3516
+
3477
3517
  if (
3478
- typeof(requestStorage) == 'undefined'
3518
+ typeof(requestStorage) == 'undefined'
3479
3519
  ||
3480
- typeof(requestStorage) != 'undefined'
3481
- && typeof(requestStorage.haltedRequest) == 'undefined'
3520
+ typeof(requestStorage) != 'undefined'
3521
+ && typeof(requestStorage.haltedRequest) == 'undefined'
3482
3522
  ) {
3483
3523
  var error = new ApiError('`requestStorage.haltedRequest` is required', 424);
3484
3524
  self.throwError(error);
@@ -3493,11 +3533,11 @@ function SuperController(options) {
3493
3533
  if (req.method.toLowerCase() == method) {
3494
3534
  data = merge(data, req[method])
3495
3535
  }
3496
-
3497
- delete req[method];
3536
+
3537
+ delete req[method];
3498
3538
  }
3499
-
3500
-
3539
+
3540
+
3501
3541
  var dataAsParams = {};
3502
3542
  if (data.count() > 0) {
3503
3543
  dataAsParams = JSON.clone(haltedRequest.data);
@@ -3509,25 +3549,25 @@ function SuperController(options) {
3509
3549
  requiredController = self.requireController(haltedRequest.routing.namespace, self._options );
3510
3550
  } catch (err) {
3511
3551
  self.throwError(err);
3512
- }
3552
+ }
3513
3553
  }
3514
3554
  req.routing = haltedRequest.routing;
3515
3555
  req.method = haltedRequest.method;
3516
3556
  req[haltedRequest.method] = data;
3517
-
3557
+
3518
3558
  local.haltedRequestUrlResumed = true;
3519
- if ( /GET/i.test(req.method) ) {
3559
+ if ( /GET/i.test(req.method) ) {
3520
3560
  if ( typeof(requestStorage.haltedRequest) != 'undefined' ) {
3521
3561
  delete requestStorage.haltedRequest;
3522
3562
  }
3523
3563
  delete requestStorage.haltedRequest;
3524
3564
  delete requestStorage.inheritedData;
3525
3565
  requestStorage.haltedRequestUrlResumed = url;
3526
-
3566
+
3527
3567
  requiredController.redirect(url, true);
3528
3568
  } else {
3529
3569
  local.onHaltedRequestResumed = function(err) {
3530
- if (!err) {
3570
+ if (!err) {
3531
3571
  delete requestStorage.haltedRequest;
3532
3572
  delete requestStorage.inheritedData;
3533
3573
  }
@@ -3535,7 +3575,7 @@ function SuperController(options) {
3535
3575
  if ( typeof(next) == 'function' ) {
3536
3576
  console.warn('About to override `next` param');
3537
3577
  }
3538
-
3578
+
3539
3579
  try {
3540
3580
  requiredController[req.routing.param.control](req, res, next);
3541
3581
  // consuming it
@@ -3544,12 +3584,12 @@ function SuperController(options) {
3544
3584
  console.error('[ BUNDLE ][ '+ local.options.conf.bundle +' ][ Controller ] Could not resume haltedRequest\n' + err.stack );
3545
3585
  self.throwError(err);
3546
3586
  }
3547
-
3548
-
3549
- }
3587
+
3588
+
3589
+ }
3550
3590
  }
3551
-
3552
-
3591
+
3592
+
3553
3593
  this.renderCustomError = function (req, res, next) {
3554
3594
 
3555
3595
  // preventing multiple call of self.renderWithoutLayout() when controller is rendering from another required controller
@@ -3559,13 +3599,13 @@ function SuperController(options) {
3559
3599
  local.options.isRenderingCustomError = true;
3560
3600
 
3561
3601
  //local.options.isWithoutLayout = true;
3562
-
3602
+
3563
3603
  var data = null;
3564
3604
  if ( typeof(req.routing.param.error) != 'undefined' ) {
3565
3605
  data = JSON.clone(req.routing.param.error) || {};
3566
3606
  delete req.routing.param.error
3567
3607
  }
3568
-
3608
+
3569
3609
  var session = getSession();
3570
3610
  if (session) {
3571
3611
  data.session = JSON.clone(session)
@@ -3603,13 +3643,13 @@ function SuperController(options) {
3603
3643
  //assets: {}
3604
3644
  };
3605
3645
  errOptions = merge(localOptions, local.options);
3606
-
3607
-
3646
+
3647
+
3608
3648
  }
3609
3649
  delete local.options.namespace;
3610
3650
  self.render(data, displayToolbar, errOptions);
3611
3651
  }
3612
-
3652
+
3613
3653
 
3614
3654
  /**
3615
3655
  * Throw error
@@ -3623,7 +3663,7 @@ function SuperController(options) {
3623
3663
  this.throwError = function(res, code, msg) {
3624
3664
  self.isProcessingError = true;
3625
3665
  var errorObject = null; // to be returned
3626
-
3666
+
3627
3667
  // preventing multiple call of self.throwError() when controller is rendering from another required controller
3628
3668
  if (local.options.renderingStack.length > 1) {
3629
3669
  return false
@@ -3634,21 +3674,21 @@ function SuperController(options) {
3634
3674
  // err.fallback must be a valide route object or a url string
3635
3675
  var fallback = null;
3636
3676
  var standardErrorMessage = null;
3637
- if (
3638
- arguments[0] instanceof Error
3677
+ if (
3678
+ arguments[0] instanceof Error
3639
3679
  || arguments.length == 1 && typeof(res) == 'object'
3640
3680
  || arguments[arguments.length-1] instanceof Error
3641
- || typeof(arguments[arguments.length-1]) == 'string' && !(arguments[0] instanceof Error)
3681
+ || typeof(arguments[arguments.length-1]) == 'string' && !(arguments[0] instanceof Error)
3642
3682
  ) {
3643
-
3644
- code = ( res && typeof(res.status) != 'undefined' ) ? res.status : 500;
3645
-
3683
+
3684
+ code = ( res && typeof(res.status) != 'undefined' ) ? res.status : 500;
3685
+
3646
3686
  if ( typeof(statusCodes[code]) != 'undefined' ) {
3647
3687
  standardErrorMessage = statusCodes[code];
3648
3688
  } else {
3649
3689
  console.warn('[ ApiValidator ] statusCode `'+ code +'` not matching any definition in `'+_( getPath('gina').core + '/status.codes')+'`\nPlease contact the Gina dev team to add one if required');
3650
3690
  }
3651
-
3691
+
3652
3692
  errorObject = {
3653
3693
  status : code,
3654
3694
  error : res.error || res.message || standardErrorMessage
@@ -3663,17 +3703,17 @@ function SuperController(options) {
3663
3703
  } else if (res.message) {
3664
3704
  console.warn('[ Controller ] Ignoring message because of the format.\n'+res.message)
3665
3705
  }
3666
-
3706
+
3667
3707
  } else if ( typeof(arguments[arguments.length-1]) == 'string' ) {
3668
3708
  // formated error
3669
3709
  errorObject.message = arguments[arguments.length-1]
3670
3710
  } else if (
3671
- arguments[arguments.length-1] instanceof Error
3672
- || typeof(res) == 'object' && typeof(res.stack) != 'undefined'
3711
+ arguments[arguments.length-1] instanceof Error
3712
+ || typeof(res) == 'object' && typeof(res.stack) != 'undefined'
3673
3713
  ) {
3674
3714
  errorObject = merge(arguments[arguments.length-1], errorObject)
3675
3715
  }
3676
-
3716
+
3677
3717
  if ( typeof(res.fallback) != 'undefined' ) {
3678
3718
  fallback = res.fallback
3679
3719
  }
@@ -3685,27 +3725,27 @@ function SuperController(options) {
3685
3725
  code = res || 500;
3686
3726
  res = local.res;
3687
3727
  }
3688
-
3728
+
3689
3729
  var responseHeaders = res.getHeaders() || local.res.getHeaders();
3690
3730
  var req = local.req;
3691
3731
  var next = local.next;
3692
3732
  if (!res.headersSent) {
3693
3733
  // DELETE request methods don't normaly use a view,
3694
3734
  // but if we are calling it from a view, we should render the error back to the view
3695
- if ( self.isXMLRequest() || !hasViews() && !/delete/i.test(req.method) || !local.options.isUsingTemplate && !hasViews() || hasViews() && !local.options.isUsingTemplate ) {
3735
+ if ( self.isXMLRequest() || !hasViews() && !/delete/i.test(req.method) || !local.options.isUsingTemplate && !hasViews() || hasViews() && !local.options.isUsingTemplate ) {
3696
3736
  // fallback interception
3697
- if ( fallback ) {
3737
+ if ( fallback ) {
3698
3738
  if ( typeof(fallback) == 'string' ){ // string url: user provided
3699
3739
  return self.redirect( fallback, true )
3700
3740
  } else {
3701
3741
  // else, using url from route object
3702
3742
  // Reminder
3703
3743
  // Here, we use route.toUrl() intead of
3704
- // route.url to support x-bundle com
3744
+ // route.url to support x-bundle com
3705
3745
  return self.redirect( fallback.toUrl() );
3706
3746
  }
3707
3747
  }
3708
-
3748
+
3709
3749
  // allowing this.throwError(err)
3710
3750
  if ( typeof(code) == 'object' && !msg && typeof(code.status) != 'undefined' && typeof(code.error) != 'undefined' ) {
3711
3751
  msg = code.error || code.message;
@@ -3717,7 +3757,7 @@ function SuperController(options) {
3717
3757
  console.warn('[ ApiValidator ] statusCode `'+ code +'` not matching any definition in `'+_( getPath('gina').core + '/status.codes')+'`\nPlease contact the Gina dev team to add one if required');
3718
3758
  }
3719
3759
 
3720
- // if ( !local.res.getHeaders()['content-type'] /**!req.headers['content-type'] */  ) {
3760
+ // if ( !local.res.getHeaders()['content-type'] /**!req.headers['content-type'] */ ) {
3721
3761
  // // Internet Explorer override
3722
3762
  // if ( typeof(req.headers['user-agent']) != 'undefined' && /msie/i.test(req.headers['user-agent']) ) {
3723
3763
  // res.writeHead(code, "content-type", "text/plain")
@@ -3725,7 +3765,7 @@ function SuperController(options) {
3725
3765
  // res.writeHead(code, { 'content-type': bundleConf.server.coreConfiguration.mime['json']} );
3726
3766
  // }
3727
3767
  // }
3728
-
3768
+
3729
3769
  // TODO - test with internet explorer then remove this if working
3730
3770
  if ( typeof(req.headers['user-agent']) != 'undefined' ) {
3731
3771
  if ( /msie/i.test(req.headers['user-agent']) ) {
@@ -3743,8 +3783,8 @@ function SuperController(options) {
3743
3783
  res.writeHead(code, "content-type", bundleConf.server.coreConfiguration.mime['json']+ '; charset='+ bundleConf.encoding);
3744
3784
  }
3745
3785
 
3746
-
3747
-
3786
+
3787
+
3748
3788
  if (!errorObject) {
3749
3789
  errorObject = {
3750
3790
  status: code,
@@ -3754,7 +3794,7 @@ function SuperController(options) {
3754
3794
  stack: msg.stack
3755
3795
  }
3756
3796
  }
3757
-
3797
+
3758
3798
  var errOutput = null, output = errorObject.toString();
3759
3799
  if ( output == '[object Object]' ) {
3760
3800
  errOutput = JSON.stringify(errorObject);
@@ -3762,19 +3802,20 @@ function SuperController(options) {
3762
3802
  errOutput = JSON.stringify(
3763
3803
  {
3764
3804
  status : errorObject.status,
3765
- error : output
3805
+ error : output,
3806
+ stack : errorObject.stack || null
3766
3807
  }
3767
3808
  );
3768
3809
  }
3769
-
3770
- console.error('[ BUNDLE ][ '+ bundleConf.bundle +' ][ Controller ] '+ req.method +' ['+res.statusCode +'] '+ req.url +'\n'+ errOutput);
3810
+
3811
+ console.error('[ BUNDLE ][ '+ bundleConf.bundle +' ][ Controller ] '+ req.method +' ['+res.statusCode +'] '+ req.url +'\n'+ errorObject);
3771
3812
  return res.end(errOutput);
3772
3813
  } else {
3773
-
3774
-
3775
- console.error(req.method +' ['+ errorObject.status +'] '+ req.url);
3776
-
3777
-
3814
+
3815
+
3816
+ console.error(req.method +' ['+ errorObject.status +'] '+ req.url + '\n'+ (errorObject.stack||errorObject.message));
3817
+
3818
+
3778
3819
  // intercept none HTML mime types
3779
3820
  var url = unescape(local.req.url) /// avoid %20
3780
3821
  , ext = null
@@ -3788,9 +3829,12 @@ function SuperController(options) {
3788
3829
  }
3789
3830
  if ( !ext || /^(html|htm)$/i.test(ext) ) {
3790
3831
  isHtmlContent = true;
3832
+ if (!ext) {
3833
+ ext = 'html'
3834
+ }
3791
3835
  }
3792
-
3793
- if (
3836
+
3837
+ if (
3794
3838
  isHtmlContent
3795
3839
  && typeof(bundleConf.content.templates._common.errorFiles) != 'undefined'
3796
3840
  && typeof(bundleConf.content.templates._common.errorFiles[code]) != 'undefined'
@@ -3810,11 +3854,11 @@ function SuperController(options) {
3810
3854
  //message : errorObject.message || msg || null,
3811
3855
  pathname : url
3812
3856
  };
3813
-
3857
+
3814
3858
  if ( errorObject ) {
3815
3859
  eData = merge(errorObject, eData);
3816
3860
  }
3817
-
3861
+
3818
3862
  if ( typeof(msg) == 'object' ) {
3819
3863
  if ( typeof(msg.stack) != 'undefined' ) {
3820
3864
  eData.stack = msg.stack
@@ -3823,8 +3867,8 @@ function SuperController(options) {
3823
3867
  eData.message = msg.message
3824
3868
  }
3825
3869
  }
3826
- if (
3827
- code
3870
+ if (
3871
+ code
3828
3872
  // See: framework/${version}/core/status.code
3829
3873
  && typeof(bundleConf.server.coreConfiguration.statusCodes[code]) != 'undefined'
3830
3874
  ) {
@@ -3834,13 +3878,13 @@ function SuperController(options) {
3834
3878
  // if ( typeof(local.req.routing) != 'undefined' ) {
3835
3879
  // eData.routing = local.req.routing;
3836
3880
  // }
3837
-
3881
+
3838
3882
  if (typeof(bundleConf.content.templates._common.errorFiles[code]) != 'undefined') {
3839
3883
  eFilename = bundleConf.content.templates._common.errorFiles[code];
3840
3884
  } else {
3841
3885
  eFilename = bundleConf.content.templates._common.errorFiles[eCode];
3842
3886
  }
3843
-
3887
+
3844
3888
  if (!local.options.isRenderingCustomError) {
3845
3889
  var eRule = 'custom-error-page@'+ bundle;
3846
3890
  var routeObj = bundleConf.content.routing[eRule];
@@ -3851,16 +3895,16 @@ function SuperController(options) {
3851
3895
  routeObj.param.error = eData;
3852
3896
  routeObj.param.displayToolbar = self.isCacheless();
3853
3897
  routeObj.param.isLocalOptionResetNeeded = true;
3854
-
3855
-
3898
+
3899
+
3856
3900
  local.req.routing = routeObj;
3857
3901
  local.req.params.errorObject = errorObject;
3858
3902
  self.renderCustomError(local.req, res, local.next);
3859
3903
  return;
3860
3904
  }
3861
-
3905
+
3862
3906
  }
3863
-
3907
+
3864
3908
  // if (!errorObject) {
3865
3909
  // errorObject = {
3866
3910
  // status: code,
@@ -3871,7 +3915,7 @@ function SuperController(options) {
3871
3915
  // }
3872
3916
  // }
3873
3917
  var msgString = '<h1 class="status">Error '+ code +'.</h1>';
3874
-
3918
+
3875
3919
  console.error('[ BUNDLE ][ '+ local.options.conf.bundle +' ][ Controller ] `this.'+ req.routing.param.control +'(...)` ['+res.statusCode +'] '+ req.url);
3876
3920
  if ( typeof(msg) == 'object' ) {
3877
3921
 
@@ -3913,7 +3957,7 @@ function SuperController(options) {
3913
3957
  if (typeof(errorObject) != 'undefined' && errorObject && typeof(errorObject.stack) != 'undefined' ) {
3914
3958
  stack = errorObject.stack
3915
3959
  }
3916
-
3960
+
3917
3961
  if (title) {
3918
3962
  msgString += '<pre class="'+ eCode +' title">'+ title +'</pre>';
3919
3963
  }
@@ -3922,7 +3966,7 @@ function SuperController(options) {
3922
3966
  }
3923
3967
  if (stack) {
3924
3968
  msgString += '<pre class="'+ eCode +' stack">'+ stack +'</pre>';
3925
- }
3969
+ }
3926
3970
  }
3927
3971
  res.writeHead(code, { 'content-type': bundleConf.server.coreConfiguration.mime[ext]+'; charset='+ bundleConf.encoding } );
3928
3972
  // if ( isHtmlContent && hasCustomErrorFile ) {
@@ -3931,7 +3975,7 @@ function SuperController(options) {
3931
3975
  //if ( isHtmlContent && !hasCustomErrorFile ) {
3932
3976
  res.end(msgString);
3933
3977
  //}
3934
-
3978
+
3935
3979
  return;
3936
3980
  }
3937
3981
  } else {