gina 0.1.6 → 0.1.7

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 (349) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +6 -0
  3. package/framework/v0.1.7/VERSION +1 -0
  4. package/framework/{v0.1.6 → v0.1.7}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.gz +0 -0
  5. package/framework/{v0.1.6 → v0.1.7}/core/asset/plugin/dist/vendor/gina/html/toolbar.html.gz +0 -0
  6. package/framework/{v0.1.6 → v0.1.7}/core/asset/plugin/dist/vendor/gina/js/gina.js +11 -0
  7. package/framework/{v0.1.6 → v0.1.7}/core/asset/plugin/dist/vendor/gina/js/gina.min.js +31 -31
  8. package/framework/v0.1.7/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
  9. package/framework/v0.1.7/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
  10. package/framework/{v0.1.6 → v0.1.7}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.gz +0 -0
  11. package/framework/{v0.1.6 → v0.1.7}/core/config.js +4 -2
  12. package/framework/{v0.1.6 → v0.1.7}/core/connectors/couchbase/index.js +97 -30
  13. package/framework/{v0.1.6 → v0.1.7}/core/controller/controller.js +54 -9
  14. package/framework/{v0.1.6 → v0.1.7}/core/controller/controller.render-json.js +52 -14
  15. package/framework/{v0.1.6 → v0.1.7}/core/controller/controller.render-swig.js +65 -6
  16. package/framework/{v0.1.6 → v0.1.7}/core/model/entity.js +117 -34
  17. package/framework/{v0.1.6 → v0.1.7}/core/server.isaac.js +92 -15
  18. package/framework/{v0.1.6 → v0.1.7}/core/server.js +35 -1
  19. package/framework/{v0.1.6 → v0.1.7}/core/template/conf/env.json +3 -1
  20. package/framework/{v0.1.6 → v0.1.7}/core/template/conf/settings.json +6 -7
  21. package/framework/{v0.1.6 → v0.1.7}/helpers/context.js +7 -6
  22. package/framework/v0.1.7/lib/cache/README.md +158 -0
  23. package/framework/v0.1.7/lib/cache/src/main.js +491 -0
  24. package/framework/v0.1.7/lib/cmd/cache/stats.js +230 -0
  25. package/framework/{v0.1.6 → v0.1.7}/lib/routing/src/main.js +11 -0
  26. package/migration_note.md +257 -0
  27. package/package.json +5 -5
  28. package/script/pre_publish.js +207 -0
  29. package/utils/helper.js +33 -0
  30. package/bin/gina.bat +0 -8
  31. package/framework/v0.1.6/VERSION +0 -1
  32. package/framework/v0.1.6/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
  33. package/framework/v0.1.6/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
  34. package/framework/v0.1.6/lib/cache/README.md +0 -19
  35. package/framework/v0.1.6/lib/cache/src/main.js +0 -279
  36. /package/framework/{v0.1.6 → v0.1.7}/AUTHORS +0 -0
  37. /package/framework/{v0.1.6 → v0.1.7}/LICENSE +0 -0
  38. /package/framework/{v0.1.6 → v0.1.7}/core/asset/html/nolayout.html +0 -0
  39. /package/framework/{v0.1.6 → v0.1.7}/core/asset/html/static.html +0 -0
  40. /package/framework/{v0.1.6 → v0.1.7}/core/asset/img/android-chrome-192x192.png +0 -0
  41. /package/framework/{v0.1.6 → v0.1.7}/core/asset/img/android-chrome-512x512.png +0 -0
  42. /package/framework/{v0.1.6 → v0.1.7}/core/asset/img/apple-touch-icon.png +0 -0
  43. /package/framework/{v0.1.6 → v0.1.7}/core/asset/img/favicon-16x16.png +0 -0
  44. /package/framework/{v0.1.6 → v0.1.7}/core/asset/img/favicon-32x32.png +0 -0
  45. /package/framework/{v0.1.6 → v0.1.7}/core/asset/img/favicon.ico +0 -0
  46. /package/framework/{v0.1.6 → v0.1.7}/core/asset/plugin/README.md +0 -0
  47. /package/framework/{v0.1.6 → v0.1.7}/core/asset/plugin/dist/vendor/gina/css/gina.min.css +0 -0
  48. /package/framework/{v0.1.6 → v0.1.7}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.br +0 -0
  49. /package/framework/{v0.1.6 → v0.1.7}/core/asset/plugin/dist/vendor/gina/html/toolbar.html +0 -0
  50. /package/framework/{v0.1.6 → v0.1.7}/core/asset/plugin/dist/vendor/gina/html/toolbar.html.br +0 -0
  51. /package/framework/{v0.1.6 → v0.1.7}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js +0 -0
  52. /package/framework/{v0.1.6 → v0.1.7}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.br +0 -0
  53. /package/framework/{v0.1.6 → v0.1.7}/core/asset/plugin/uuid.json +0 -0
  54. /package/framework/{v0.1.6 → v0.1.7}/core/connectors/couchbase/lib/connector.js +0 -0
  55. /package/framework/{v0.1.6 → v0.1.7}/core/connectors/couchbase/lib/connector.v2.js +0 -0
  56. /package/framework/{v0.1.6 → v0.1.7}/core/connectors/couchbase/lib/connector.v3.js +0 -0
  57. /package/framework/{v0.1.6 → v0.1.7}/core/connectors/couchbase/lib/connector.v4.js +0 -0
  58. /package/framework/{v0.1.6 → v0.1.7}/core/connectors/couchbase/lib/n1ql.js +0 -0
  59. /package/framework/{v0.1.6 → v0.1.7}/core/connectors/couchbase/lib/session-store.js +0 -0
  60. /package/framework/{v0.1.6 → v0.1.7}/core/connectors/couchbase/lib/session-store.v2.js +0 -0
  61. /package/framework/{v0.1.6 → v0.1.7}/core/connectors/couchbase/lib/session-store.v3.js +0 -0
  62. /package/framework/{v0.1.6 → v0.1.7}/core/connectors/couchbase/lib/session-store.v4.js +0 -0
  63. /package/framework/{v0.1.6 → v0.1.7}/core/content.encoding +0 -0
  64. /package/framework/{v0.1.6 → v0.1.7}/core/controller/controller.framework.js +0 -0
  65. /package/framework/{v0.1.6 → v0.1.7}/core/controller/controller.render-v1.js +0 -0
  66. /package/framework/{v0.1.6 → v0.1.7}/core/controller/index.js +0 -0
  67. /package/framework/{v0.1.6 → v0.1.7}/core/deps/busboy-1.6.0/LICENSE +0 -0
  68. /package/framework/{v0.1.6 → v0.1.7}/core/deps/busboy-1.6.0/README.md +0 -0
  69. /package/framework/{v0.1.6 → v0.1.7}/core/deps/busboy-1.6.0/lib/index.js +0 -0
  70. /package/framework/{v0.1.6 → v0.1.7}/core/deps/busboy-1.6.0/lib/types/multipart.js +0 -0
  71. /package/framework/{v0.1.6 → v0.1.7}/core/deps/busboy-1.6.0/lib/types/urlencoded.js +0 -0
  72. /package/framework/{v0.1.6 → v0.1.7}/core/deps/busboy-1.6.0/lib/utils.js +0 -0
  73. /package/framework/{v0.1.6 → v0.1.7}/core/deps/busboy-1.6.0/package.json +0 -0
  74. /package/framework/{v0.1.6 → v0.1.7}/core/deps/optimist-0.6.1/LICENSE +0 -0
  75. /package/framework/{v0.1.6 → v0.1.7}/core/deps/optimist-0.6.1/index.js +0 -0
  76. /package/framework/{v0.1.6 → v0.1.7}/core/deps/optimist-0.6.1/package.json +0 -0
  77. /package/framework/{v0.1.6 → v0.1.7}/core/deps/optimist-0.6.1/readme.markdown +0 -0
  78. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/HISTORY.md +0 -0
  79. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/LICENSE +0 -0
  80. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/README.md +0 -0
  81. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/bin/swig.js +0 -0
  82. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/dist/swig.min.js +0 -0
  83. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/index.js +0 -0
  84. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/dateformatter.js +0 -0
  85. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/filters.js +0 -0
  86. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/lexer.js +0 -0
  87. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/loaders/filesystem.js +0 -0
  88. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/loaders/index.js +0 -0
  89. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/loaders/memory.js +0 -0
  90. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/parser.js +0 -0
  91. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/swig.js +0 -0
  92. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/tags/autoescape.js +0 -0
  93. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/tags/block.js +0 -0
  94. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/tags/else.js +0 -0
  95. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/tags/elseif.js +0 -0
  96. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/tags/extends.js +0 -0
  97. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/tags/filter.js +0 -0
  98. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/tags/for.js +0 -0
  99. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/tags/if.js +0 -0
  100. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/tags/import.js +0 -0
  101. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/tags/include.js +0 -0
  102. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/tags/index.js +0 -0
  103. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/tags/macro.js +0 -0
  104. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/tags/parent.js +0 -0
  105. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/tags/raw.js +0 -0
  106. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/tags/set.js +0 -0
  107. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/tags/spaceless.js +0 -0
  108. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/lib/utils.js +0 -0
  109. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-1.4.2/package.json +0 -0
  110. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-client/swig-2.0.0.min.js +0 -0
  111. /package/framework/{v0.1.6 → v0.1.7}/core/deps/swig-client/swig.js +0 -0
  112. /package/framework/{v0.1.6 → v0.1.7}/core/dev/index.js +0 -0
  113. /package/framework/{v0.1.6 → v0.1.7}/core/dev/lib/class.js +0 -0
  114. /package/framework/{v0.1.6 → v0.1.7}/core/dev/lib/factory.js +0 -0
  115. /package/framework/{v0.1.6 → v0.1.7}/core/dev/lib/tools.js +0 -0
  116. /package/framework/{v0.1.6 → v0.1.7}/core/gna.js +0 -0
  117. /package/framework/{v0.1.6 → v0.1.7}/core/locales/README.md +0 -0
  118. /package/framework/{v0.1.6 → v0.1.7}/core/locales/currency.json +0 -0
  119. /package/framework/{v0.1.6 → v0.1.7}/core/locales/dist/language/en.json +0 -0
  120. /package/framework/{v0.1.6 → v0.1.7}/core/locales/dist/language/fr.json +0 -0
  121. /package/framework/{v0.1.6 → v0.1.7}/core/locales/dist/region/en.json +0 -0
  122. /package/framework/{v0.1.6 → v0.1.7}/core/locales/dist/region/fr.json +0 -0
  123. /package/framework/{v0.1.6 → v0.1.7}/core/locales/index.js +0 -0
  124. /package/framework/{v0.1.6 → v0.1.7}/core/mime.types +0 -0
  125. /package/framework/{v0.1.6 → v0.1.7}/core/model/index.js +0 -0
  126. /package/framework/{v0.1.6 → v0.1.7}/core/model/template/entityFactory.js +0 -0
  127. /package/framework/{v0.1.6 → v0.1.7}/core/model/template/index.js +0 -0
  128. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/README.md +0 -0
  129. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/index.js +0 -0
  130. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/lib/file/README.md +0 -0
  131. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/lib/file/build.json +0 -0
  132. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/lib/file/package.json +0 -0
  133. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/lib/intl/README.md +0 -0
  134. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/lib/intl/build.json +0 -0
  135. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/lib/intl/package.json +0 -0
  136. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/lib/intl/src/main.js +0 -0
  137. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/lib/storage/README.md +0 -0
  138. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/lib/storage/build.json +0 -0
  139. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/lib/storage/package.json +0 -0
  140. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/lib/storage/src/main.js +0 -0
  141. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/lib/validator/README.md +0 -0
  142. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/lib/validator/build.json +0 -0
  143. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/lib/validator/package.json +0 -0
  144. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/lib/validator/src/form-validator.js +0 -0
  145. /package/framework/{v0.1.6 → v0.1.7}/core/plugins/lib/validator/src/main.js +0 -0
  146. /package/framework/{v0.1.6 → v0.1.7}/core/router.js +0 -0
  147. /package/framework/{v0.1.6 → v0.1.7}/core/server.express.js +0 -0
  148. /package/framework/{v0.1.6 → v0.1.7}/core/status.codes +0 -0
  149. /package/framework/{v0.1.6 → v0.1.7}/core/template/_gitignore +0 -0
  150. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle/config/app.json +0 -0
  151. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle/config/routing.json +0 -0
  152. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle/config/settings.json +0 -0
  153. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle/config/settings.server.json +0 -0
  154. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle/config/templates.json +0 -0
  155. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle/controllers/controller.content.js +0 -0
  156. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle/controllers/controller.js +0 -0
  157. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle/controllers/setup.js +0 -0
  158. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle/index.js +0 -0
  159. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle_namespace/controllers/controller.js +0 -0
  160. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle_public/css/default.css +0 -0
  161. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle_public/css/vendor/readme.md +0 -0
  162. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle_public/favicon.ico +0 -0
  163. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle_public/js/vendor/readme.md +0 -0
  164. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle_public/readme.md +0 -0
  165. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle_templates/handlers/main.js +0 -0
  166. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle_templates/html/content/homepage.html +0 -0
  167. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle_templates/html/includes/error-msg-noscript.html +0 -0
  168. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle_templates/html/includes/error-msg-outdated-browser.html +0 -0
  169. /package/framework/{v0.1.6 → v0.1.7}/core/template/boilerplate/bundle_templates/html/layouts/main.html +0 -0
  170. /package/framework/{v0.1.6 → v0.1.7}/core/template/command/gina.bat.tpl +0 -0
  171. /package/framework/{v0.1.6 → v0.1.7}/core/template/command/gina.tpl +0 -0
  172. /package/framework/{v0.1.6 → v0.1.7}/core/template/conf/manifest.json +0 -0
  173. /package/framework/{v0.1.6 → v0.1.7}/core/template/conf/package.json +0 -0
  174. /package/framework/{v0.1.6 → v0.1.7}/core/template/conf/statics.json +0 -0
  175. /package/framework/{v0.1.6 → v0.1.7}/core/template/conf/templates.json +0 -0
  176. /package/framework/{v0.1.6 → v0.1.7}/core/template/error/client/json/401.json +0 -0
  177. /package/framework/{v0.1.6 → v0.1.7}/core/template/error/client/json/403.json +0 -0
  178. /package/framework/{v0.1.6 → v0.1.7}/core/template/error/client/json/404.json +0 -0
  179. /package/framework/{v0.1.6 → v0.1.7}/core/template/error/server/html/50x.html +0 -0
  180. /package/framework/{v0.1.6 → v0.1.7}/core/template/error/server/json/500.json +0 -0
  181. /package/framework/{v0.1.6 → v0.1.7}/core/template/error/server/json/503.json +0 -0
  182. /package/framework/{v0.1.6 → v0.1.7}/core/template/extensions/logger/config.json +0 -0
  183. /package/framework/{v0.1.6 → v0.1.7}/helpers/console.js +0 -0
  184. /package/framework/{v0.1.6 → v0.1.7}/helpers/data/LICENSE +0 -0
  185. /package/framework/{v0.1.6 → v0.1.7}/helpers/data/README.md +0 -0
  186. /package/framework/{v0.1.6 → v0.1.7}/helpers/data/package.json +0 -0
  187. /package/framework/{v0.1.6 → v0.1.7}/helpers/data/src/main.js +0 -0
  188. /package/framework/{v0.1.6 → v0.1.7}/helpers/dateFormat.js +0 -0
  189. /package/framework/{v0.1.6 → v0.1.7}/helpers/index.js +0 -0
  190. /package/framework/{v0.1.6 → v0.1.7}/helpers/json/LICENSE +0 -0
  191. /package/framework/{v0.1.6 → v0.1.7}/helpers/json/README.md +0 -0
  192. /package/framework/{v0.1.6 → v0.1.7}/helpers/json/package.json +0 -0
  193. /package/framework/{v0.1.6 → v0.1.7}/helpers/json/src/main.js +0 -0
  194. /package/framework/{v0.1.6 → v0.1.7}/helpers/path.js +0 -0
  195. /package/framework/{v0.1.6 → v0.1.7}/helpers/plugins/README.md +0 -0
  196. /package/framework/{v0.1.6 → v0.1.7}/helpers/plugins/package.json +0 -0
  197. /package/framework/{v0.1.6 → v0.1.7}/helpers/plugins/src/api-error.js +0 -0
  198. /package/framework/{v0.1.6 → v0.1.7}/helpers/plugins/src/main.js +0 -0
  199. /package/framework/{v0.1.6 → v0.1.7}/helpers/prototypes.js +0 -0
  200. /package/framework/{v0.1.6 → v0.1.7}/helpers/task.js +0 -0
  201. /package/framework/{v0.1.6 → v0.1.7}/helpers/text.js +0 -0
  202. /package/framework/{v0.1.6 → v0.1.7}/lib/archiver/README.md +0 -0
  203. /package/framework/{v0.1.6 → v0.1.7}/lib/archiver/build.json +0 -0
  204. /package/framework/{v0.1.6 → v0.1.7}/lib/archiver/package.json +0 -0
  205. /package/framework/{v0.1.6 → v0.1.7}/lib/archiver/src/dep/jszip.min.js +0 -0
  206. /package/framework/{v0.1.6 → v0.1.7}/lib/archiver/src/main.js +0 -0
  207. /package/framework/{v0.1.6 → v0.1.7}/lib/cache/build.json +0 -0
  208. /package/framework/{v0.1.6 → v0.1.7}/lib/cache/package.json +0 -0
  209. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/aliases.json +0 -0
  210. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/bundle/add.js +0 -0
  211. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/bundle/arguments.json +0 -0
  212. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/bundle/build.js +0 -0
  213. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/bundle/copy.js +0 -0
  214. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/bundle/cp.js +0 -0
  215. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/bundle/help.js +0 -0
  216. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/bundle/help.txt +0 -0
  217. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/bundle/list.js +0 -0
  218. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/bundle/remove.js +0 -0
  219. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/bundle/rename.js +0 -0
  220. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/bundle/restart.js +0 -0
  221. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/bundle/rm.js +0 -0
  222. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/bundle/start.js +0 -0
  223. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/bundle/status.js +0 -0
  224. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/bundle/stop.js +0 -0
  225. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/env/add.js +0 -0
  226. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/env/get.js +0 -0
  227. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/env/help.js +0 -0
  228. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/env/help.txt +0 -0
  229. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/env/link-dev.js +0 -0
  230. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/env/list.js +0 -0
  231. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/env/remove.js +0 -0
  232. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/env/rm.js +0 -0
  233. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/env/set.js +0 -0
  234. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/env/unset.js +0 -0
  235. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/env/use.js +0 -0
  236. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/arguments.json +0 -0
  237. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/build.js +0 -0
  238. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/dot.js +0 -0
  239. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/get.js +0 -0
  240. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/help.js +0 -0
  241. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/help.txt +0 -0
  242. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/init.js +0 -0
  243. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/link-node-modules.js +0 -0
  244. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/link.js +0 -0
  245. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/msg.json +0 -0
  246. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/open.js +0 -0
  247. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/restart.js +0 -0
  248. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/set.js +0 -0
  249. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/start.js +0 -0
  250. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/status.js +0 -0
  251. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/stop.js +0 -0
  252. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/tail.js +0 -0
  253. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/update.js +0 -0
  254. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/framework/version.js +0 -0
  255. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/gina-dev.1.md +0 -0
  256. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/gina-framework.1.md +0 -0
  257. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/gina.1.md +0 -0
  258. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/helper.js +0 -0
  259. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/index.js +0 -0
  260. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/minion/help.js +0 -0
  261. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/minion/help.txt +0 -0
  262. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/msg.json +0 -0
  263. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/port/help.js +0 -0
  264. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/port/help.txt +0 -0
  265. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/port/inc/scan.js +0 -0
  266. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/port/list.js +0 -0
  267. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/port/reset.js +0 -0
  268. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/port/set.js +0 -0
  269. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/project/add.js +0 -0
  270. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/project/arguments.json +0 -0
  271. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/project/build.js +0 -0
  272. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/project/help.js +0 -0
  273. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/project/help.txt +0 -0
  274. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/project/import.js +0 -0
  275. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/project/list.js +0 -0
  276. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/project/move.js +0 -0
  277. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/project/remove.js +0 -0
  278. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/project/rename.js +0 -0
  279. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/project/restart.js +0 -0
  280. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/project/rm.js +0 -0
  281. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/project/start.js +0 -0
  282. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/project/status.js +0 -0
  283. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/project/stop.js +0 -0
  284. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/protocol/help.js +0 -0
  285. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/protocol/help.txt +0 -0
  286. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/protocol/list.js +0 -0
  287. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/protocol/set.js +0 -0
  288. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/scope/add.js +0 -0
  289. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/scope/help.js +0 -0
  290. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/scope/help.txt +0 -0
  291. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/scope/link-local.js +0 -0
  292. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/scope/link-production.js +0 -0
  293. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/scope/list.js +0 -0
  294. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/scope/remove.js +0 -0
  295. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/scope/rm.js +0 -0
  296. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/scope/use.js +0 -0
  297. /package/framework/{v0.1.6 → v0.1.7}/lib/cmd/view/add.js +0 -0
  298. /package/framework/{v0.1.6 → v0.1.7}/lib/collection/README.md +0 -0
  299. /package/framework/{v0.1.6 → v0.1.7}/lib/collection/build.json +0 -0
  300. /package/framework/{v0.1.6 → v0.1.7}/lib/collection/package.json +0 -0
  301. /package/framework/{v0.1.6 → v0.1.7}/lib/collection/src/main.js +0 -0
  302. /package/framework/{v0.1.6 → v0.1.7}/lib/config.js +0 -0
  303. /package/framework/{v0.1.6 → v0.1.7}/lib/cron/README.md +0 -0
  304. /package/framework/{v0.1.6 → v0.1.7}/lib/cron/package.json +0 -0
  305. /package/framework/{v0.1.6 → v0.1.7}/lib/cron/src/main.js +0 -0
  306. /package/framework/{v0.1.6 → v0.1.7}/lib/domain/LICENSE +0 -0
  307. /package/framework/{v0.1.6 → v0.1.7}/lib/domain/README.md +0 -0
  308. /package/framework/{v0.1.6 → v0.1.7}/lib/domain/dist/2025-03-14_13-41-20_UTC.dat +0 -0
  309. /package/framework/{v0.1.6 → v0.1.7}/lib/domain/dist/public_suffix_list.dat +0 -0
  310. /package/framework/{v0.1.6 → v0.1.7}/lib/domain/dist/public_suffix_list.dat.br +0 -0
  311. /package/framework/{v0.1.6 → v0.1.7}/lib/domain/dist/public_suffix_list.dat.gz +0 -0
  312. /package/framework/{v0.1.6 → v0.1.7}/lib/domain/package.json +0 -0
  313. /package/framework/{v0.1.6 → v0.1.7}/lib/domain/src/main.js +0 -0
  314. /package/framework/{v0.1.6 → v0.1.7}/lib/generator/index.js +0 -0
  315. /package/framework/{v0.1.6 → v0.1.7}/lib/index.js +0 -0
  316. /package/framework/{v0.1.6 → v0.1.7}/lib/inherits/LICENSE +0 -0
  317. /package/framework/{v0.1.6 → v0.1.7}/lib/inherits/README.md +0 -0
  318. /package/framework/{v0.1.6 → v0.1.7}/lib/inherits/package.json +0 -0
  319. /package/framework/{v0.1.6 → v0.1.7}/lib/inherits/src/main.js +0 -0
  320. /package/framework/{v0.1.6 → v0.1.7}/lib/logger/README.md +0 -0
  321. /package/framework/{v0.1.6 → v0.1.7}/lib/logger/package.json +0 -0
  322. /package/framework/{v0.1.6 → v0.1.7}/lib/logger/src/containers/default/index.js +0 -0
  323. /package/framework/{v0.1.6 → v0.1.7}/lib/logger/src/containers/file/index.js +0 -0
  324. /package/framework/{v0.1.6 → v0.1.7}/lib/logger/src/containers/file/lib/logrotator/README.md +0 -0
  325. /package/framework/{v0.1.6 → v0.1.7}/lib/logger/src/containers/file/lib/logrotator/index.js +0 -0
  326. /package/framework/{v0.1.6 → v0.1.7}/lib/logger/src/containers/mq/index.js +0 -0
  327. /package/framework/{v0.1.6 → v0.1.7}/lib/logger/src/containers/mq/listener.js +0 -0
  328. /package/framework/{v0.1.6 → v0.1.7}/lib/logger/src/containers/mq/speaker.js +0 -0
  329. /package/framework/{v0.1.6 → v0.1.7}/lib/logger/src/helper.js +0 -0
  330. /package/framework/{v0.1.6 → v0.1.7}/lib/logger/src/main.js +0 -0
  331. /package/framework/{v0.1.6 → v0.1.7}/lib/math/index.js +0 -0
  332. /package/framework/{v0.1.6 → v0.1.7}/lib/merge/README.md +0 -0
  333. /package/framework/{v0.1.6 → v0.1.7}/lib/merge/package.json +0 -0
  334. /package/framework/{v0.1.6 → v0.1.7}/lib/merge/src/main.js +0 -0
  335. /package/framework/{v0.1.6 → v0.1.7}/lib/model.js +0 -0
  336. /package/framework/{v0.1.6 → v0.1.7}/lib/proc.js +0 -0
  337. /package/framework/{v0.1.6 → v0.1.7}/lib/routing/README.md +0 -0
  338. /package/framework/{v0.1.6 → v0.1.7}/lib/routing/build.json +0 -0
  339. /package/framework/{v0.1.6 → v0.1.7}/lib/routing/package.json +0 -0
  340. /package/framework/{v0.1.6 → v0.1.7}/lib/session-store.js +0 -0
  341. /package/framework/{v0.1.6 → v0.1.7}/lib/shell.js +0 -0
  342. /package/framework/{v0.1.6 → v0.1.7}/lib/swig-filters/README.md +0 -0
  343. /package/framework/{v0.1.6 → v0.1.7}/lib/swig-filters/package.json +0 -0
  344. /package/framework/{v0.1.6 → v0.1.7}/lib/swig-filters/src/main.js +0 -0
  345. /package/framework/{v0.1.6 → v0.1.7}/lib/url/README.md +0 -0
  346. /package/framework/{v0.1.6 → v0.1.7}/lib/url/index.js +0 -0
  347. /package/framework/{v0.1.6 → v0.1.7}/lib/url/routing.json +0 -0
  348. /package/framework/{v0.1.6 → v0.1.7}/lib/validator.js +0 -0
  349. /package/framework/{v0.1.6 → v0.1.7}/package.json +0 -0
package/CHANGELOG.md CHANGED
@@ -6,6 +6,30 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
6
6
  and is generated by [Changie](https://github.com/miniscruff/changie).
7
7
 
8
8
 
9
+ ## 0.1.7 - 2026-03-20
10
+ ### Added
11
+ * Cache: sliding-window expiration and absolute ceiling (maxAge) for HTML and JSON response caches
12
+ * Added gina cache:stats <bundle> @<project> CLI command. Fetches and prints a grouped table of in-memory cache entries from a running bundle. Requires the bundle to be running.
13
+ * Cached routes now emit `Cache-Control` headers synchronised with the server-side TTL. A new optional `visibility` field (`"public" | "private"`, default `"private"`) in the per-route cache config controls the directive sent to browsers and CDNs. The hit path uses the remaining TTL so downstream caches do not over-serve stale content.
14
+ * Per-route outgoing query timeout: add "queryTimeout": <ms> to any routing.json rule and self.query() will use it as the request timeout budget when options.requestTimeout is not explicitly set. The hardcoded 10 s default still applies when neither is set.
15
+ ### Changed
16
+ * Cache FS writes in the JSON renderer are now asynchronous (fs.promises.writeFile), avoiding event-loop blocking on cache misses.
17
+ * routing.json queryTimeout field now accepts human-readable strings ("30s", "500ms", "2m", "1h") in addition to integer milliseconds (30000). The value is normalised to ms at parse time so req.routing.queryTimeout is always a number.
18
+ * app.json proxy target field "timeout" renamed to "requestTimeout" — unambiguous name for the per-request outgoing timeout. Update any app.json proxy target that declares a "timeout" to use "requestTimeout" instead. self.query() call sites that passed options.timeout must also be updated to options.requestTimeout.
19
+ * self.query() options field "timeout" renamed to "requestTimeout" — consistent with app.json::proxy.<service>.requestTimeout. The internal pipeline (both HTTP/1 and HTTP/2 handlers) and the defaultOptions fallback now use requestTimeout throughout
20
+ * Entity methods and Couchbase N1QL methods now return a native Promise (Option B). await entity.method(args) works directly without util.promisify. .onComplete(cb) remains fully backward-compatible. Removes the _isRegisteredFromProto guard that was silently dropping queries when a callback-path call preceded a Promise-path call on the same entity.
21
+ ### Fixed
22
+ * Sub-second TTL and maxAge values (e.g. ttl: 0.5) now work correctly in the cache. Previously, fractional seconds were truncated to zero, causing immediate eviction.
23
+ * Completed sub-second maxAge fix (#C1): both renderers were pre-truncating maxAge with ~~ before passing it to lib/cache, bypassing the Math.round fix. Removed ~~ from render-swig.js and render-json.js. Also fixed Cache-Status header calculation in server.isaac.js.
24
+ * Cache keys now include the bundle name ("static:{bundle}:{url}" and "data:{bundle}:{url}") to prevent silent cache collisions when two bundles serve the same URL path on the same server instance.
25
+ * Cache entries are now capped via LRU eviction. Cache(options) accepts a `maxEntries` option (default 0 = unlimited); when reached, the least-recently-accessed entry is evicted before each insert. The shared server cache defaults to 1000 entries, configurable via `server.cache.maxEntries` in env.json. The routing cache is capped at 5000 entries (FIFO).
26
+ * Fixed handler files returning 404 when a catch-all root statics mapping (empty key) was defined: staticResources is now sorted by descending path length so specific prefixes like /handlers/ are matched before / in the prefix-regex loop
27
+ * CORS preflight (OPTIONS) requests are now handled before routing: the server responds with HTTP 204 and the correct Access-Control-Allow-Origin header immediately, instead of forwarding to the controller action which returned an error without CORS headers. CORS response headers are now also included on all HTTP/2 JSON responses.
28
+ * self.query() queryTimeout fallback now fires correctly: moved the req.routing.queryTimeout check to before the merge with defaultOptions, which was silently overwriting timeout with the "10s" framework default before the check could run
29
+ * controller.render-swig.js: isRenderingCustomError now detected from both userData and localOptions (set by renderCustomError() in controller.js). Adds null-guard on userData. localOptions is now resolved before the flag check.
30
+ ### Security
31
+ * Removed dead framework version v0.1.1-alpha.1 from the repository. Its package.json declared sanitize-html ^2.5.0 (CVE-2021-26539, CVE-2021-26540 — XSS, high severity) and busboy ^0.2.14 (dicer ReDoS). Neither version nor its dependencies were in use.
32
+
9
33
  ## 0.1.6 - 2026-03-08
10
34
  ### Added
11
35
  * Added JSDoc across core/controller/, core/model/, and helpers/: constructor @class/@constructor/@extends, @inner on private helpers, complete @param/@returns on all public methods, @global on the _ path helper, @module on controller/index.js
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  [![GitHub version](https://badge.fury.io/gh/Rhinostone%2Fgina.svg)](https://badge.fury.io/gh/Rhinostone%2Fgina) [![npm version](https://badge.fury.io/js/gina.svg)](https://badge.fury.io/js/gina)
4
4
 
5
+ > **Documentation:** [https://gina.io/docs/](https://gina.io/docs/)
6
+
5
7
  <strong>Gina I/O</strong> - Node.js MVC and Event Driven framework
6
8
 
7
9
  > We are looking for people to help us test and improve `Windows` support.
@@ -613,6 +615,10 @@ After this, try again to start, it should run better.
613
615
 
614
616
  More documentation and tutorials are coming soon !
615
617
 
618
+ ---
619
+
620
+ For the full documentation, visit [https://gina.io/docs/](https://gina.io/docs/)
621
+
616
622
  ## License (MIT)
617
623
 
618
624
  Copyright © 2009-2026 [Rhinostone](http://www.rhinostone.com/)
@@ -0,0 +1 @@
1
+ 0.1.7
@@ -4670,6 +4670,10 @@ function Routing() {
4670
4670
  return self;
4671
4671
  }
4672
4672
 
4673
+ // Maximum number of distinct route IDs kept in the route cache.
4674
+ // When exceeded, the oldest entry (insertion order) is evicted first.
4675
+ var MAX_CACHED_ROUTES = 5000;
4676
+
4673
4677
 
4674
4678
  self.allowedMethodsString = self.allowedMethods.join(',');
4675
4679
 
@@ -4793,6 +4797,10 @@ function Routing() {
4793
4797
  */
4794
4798
  self.cache = function(routeId, name, routeObject, params, methodParams) {
4795
4799
  if ( Routing._cached.indexOf(routeId) == -1 ) {
4800
+ // FIFO eviction: when at capacity, drop the oldest entry before inserting
4801
+ if ( Routing._cached.length >= MAX_CACHED_ROUTES ) {
4802
+ self.invalidateCached(Routing._cached[0]);
4803
+ }
4796
4804
  Routing._cached.push(routeId);
4797
4805
  Routing._cachedRoutes[routeId] = {
4798
4806
  name : name,
@@ -4840,6 +4848,9 @@ function Routing() {
4840
4848
  if ( typeof(routeObject.cache) != 'undefined' ) {
4841
4849
  params.cache = routeObject.cache;
4842
4850
  }
4851
+ if ( typeof(routeObject.queryTimeout) != 'undefined' ) {
4852
+ params.queryTimeout = parseTimeout(routeObject.queryTimeout);
4853
+ }
4843
4854
 
4844
4855
  // isRoute
4845
4856
  return self.compareUrls(params, routeObject.url, req);
@@ -113,37 +113,37 @@ delete n[y][z]:('undefined'==typeof r[y].errors&&(r[y].errors={}),r[y].errors[z]
113
113
  function Routing(){var A='undefined'!==typeof module&&module.exports?!1:!0,P={allowedMethods:['get','post','put','delete'],reservedParams:['controle','file','title','namespace','path'],notFound:{},getInstance:function(r){return Routing.instance}};if('undefined'==typeof Routing.initialized)Routing.initialized=!0,Routing.instance=P,Routing._cached=[],Routing._cachedRoutes={};else return P=P.getInstance();P.allowedMethodsString=P.allowedMethods.join(',');var V=null,ja=null,R=null;A?(ja&&'function'==
114
114
  typeof ja||(ja=require('lib/merge')),R&&'function'==typeof R||(R=require('lib/form-validator'))):(require('fs'),require('util'),require('../../inherits'),ja=require('../../merge'),V=require(__dirname+'/../../../core/plugins')||getContext('gina').plugins,R=V.Validator);P.getUrlProps=function(r,H){var v={};if(A){var wa=window.gina.config;v.hostname=wa.hostname;'undefined'!=typeof r&&(r=this.getRoute('webroot@'+r),v.hostname=r.hostname,v.host=r.host,v.webroot=r.webroot)}else wa=getContext('gina').config,
115
115
  'undefined'!=typeof getContext('argvFilename')&&(wa.getRouting=getContext('gina').Config.instance.getRouting),'undefined'==typeof r&&(r=wa.bundle),'undefined'==typeof H&&(H=wa.env),v.hostname=wa.envConf[r][H].hostname,v.host=wa.envConf[r][H].host,v.webroot=wa.envConf[r][H].server.webroot,console.debug('[self.getUrlProps][isProxyHost = '+getContext('isProxyHost')+'] hostname ',wa.envConf[r][H].hostname,vs,process.gina.PROXY_HOSTNAME);return v};P.cache=function(r,H,v,wa,Fa){-1==Routing._cached.indexOf(r)&&
116
- (Routing._cached.push(r),Routing._cachedRoutes[r]={name:H,routing:v,params:wa,methodParams:Fa})};P.getCached=function(r,H){if(-1<Routing._cached.indexOf(r)){var v=Routing._cachedRoutes[r],wa=H.method.toLowerCase();r=JSON.clone(v.routing);v={method:wa,requirements:r.requirements,namespace:r.namespace||void 0,url:decodeURI(H.url),rule:r.originalRule||v.name,param:r.param,middleware:r.middleware,bundle:r.bundle,isXMLRequest:H.isXMLRequest,isWithCredentials:H.isWithCredentials};'undefined'==typeof r.rule&&
117
- 'undefined'!=typeof v.rule&&(r.rule=v.rule);'undefined'!=typeof r.cache&&(v.cache=r.cache);return P.compareUrls(v,r.url,H)}return null};P.invalidateCached=function(r){-1<Routing._cached.indexOf(r)&&(Routing._cached.splice(Routing._cached.indexOf(r),1),delete Routing._cachedRoutes[r])};P.compareUrls=async function(r,H,v,wa,Fa){'undefined'==typeof v&&(v={routing:{}});if(/,/.test(H)){var T=0;H=H.split(/,/g);for(var J=H.length,G={past:!1,request:v};T<J&&!G.past;)G=await N(r,H[T],v,wa,Fa),++T;return G}return await N(r,
118
- H,v,wa,Fa)};var N=async function(r,H,v,wa,Fa){var T=null;try{T=r.url.split(/\//)}catch(U){console.warn(U),T=['']}H=H.split(/\//);var J=0,G=0,B=H.length,n=0,y={},z=0,D=v.method.toLowerCase(),w='get';try{w=r.method.toLowerCase()}catch(U){}var x=!1;if('undefined'!=typeof r.requirements&&/get|delete/i.test(D)&&'undefined'!=typeof v[D]||'undefined'!=typeof r.requirements&&/get/i.test(D)&&/delete/i.test(w)){/get/i.test(D)&&/delete/i.test(w)&&(D=w);if(/^(delete)$/i.test(D)&&T.length===H.length){'undefined'==
119
- typeof v[D]&&(v[D]={});for(let U=0,pa=H.length;U<pa;U++)if(T[U]===H[U])++n;else if(w=H[U].substring(1),'undefined'!=typeof r.requirements[w]){w=r.requirements[w];if(/^\//.test(w))w=w.substring(1,w.lastIndexOf('/')-1);else if(/^validator::/.test(w)&&await ha(H[U],T[U],r,v,wa,Fa)){++n;continue}/^:/.test(H[U])&&'undefined'!=typeof w&&(new RegExp(w)).test(T[U])&&(++n,v[D][H[U].substring(1)]=T[U])}x=!0}for(var E in v[D])'undefined'!=typeof r.requirements[E]&&0>H.indexOf(':'+E)&&(H[G]=':'+E,++G,T[J]=v[D][E],
120
- ++J,x||T.length!==H.length||++B)}if(!x&&T.length===H.length)for(;z<B;++z)T[z]===H[z]?++n:n==z&&/:/.test(H[z])&&await ha(H[z],T[z],r,v,wa,Fa)&&++n;if('undefined'!=typeof r.requirements&&D==r.method.toLowerCase()&&!x&&n>=B)for(E=Object.getOwnPropertyNames(r.requirements),J=0,H.join(',').match(/:[-_a-z0-9]+/g);J<E.length;){G=E[J];if('undefined'==typeof r.param[G]&&/^validator::/i.test(r.requirements[G])){if(H.length!=T.length)break;var O=H.join(',').match(/:[-_a-z0-9]+/g);let U=r.requirements[G];z={};
121
- w={};x={};try{w=JSON.parse(U.split(/::/).splice(1)[0].replace(/([^:"\s+](\w+)):/g,'"$1":').replace(/([^:"\s+](\w+))\s+:/g,'"$1":'))}catch(pa){throw pa;}if('undefined'!=typeof w.query&&'undefined'!=typeof w.query.data){z=w.query.data;for(let pa in z)0>O.indexOf(z[pa])&&delete z[pa];for(let pa=0,Ea=H.length;pa<Ea;pa++)/^:/.test(H[pa])&&(O=H[pa].replace(/^:/,''),''!=O&&'undefined'!=typeof T[pa]&&(z[O]=T[pa],'undefined'==typeof v.params[O]&&(v.params[O]=T[pa])))}z=ja(z,JSON.clone(v[D])||{});'undefined'==
122
- typeof z[G]&&(z[G]=null);x[G]=w;_validator=A?new R(z):new R('routing',z,null,x);if(0==w.count()){console.error('Route validation failed '+r.rule);--n;J++;continue}for(let pa in w)if('undefined'!=typeof w[pa].data&&(w[pa].data=z),x=Array.isArray(w[pa])?await _validator[G][pa].apply(_validator[G],w[pa]):await _validator[G][pa](w[pa],v,wa,Fa),!x.isValid&&(--n,'undefined'!=typeof x.error))throw x.error;}J++}y.past=n===B?!0:!1;y.past&&(v.routing=S(r,v[D]),y.request=v);return y},ha=async function(r,H,v,
123
- wa,Fa,T){var J=-1,G=r.match(/:\w+/g);J=new RegExp(r,'g');var B=null,n=null,y=null;B=!1;var z=B=n=n=null,D=null,w=wa.method.toLowerCase();if(!G.length)return!1;v.param.path&&J.test(v.param.path)&&(v.param.path=v.param.path.replace(J,H));v.param.namespace&&J.test(v.param.namespace)&&(v.param.namespace=v.param.namespace.replace(J,H));'undefined'!=typeof v.param.file&&/:/.test(v.param.file)&&(B=new RegExp('(:'+r+'/|:'+r+'$)','g'),Q.variable=H,v.param.file=v.param.file.replace(B,Q),B=null);v.param.title&&
124
- J.test(v.param.title)&&(v.param.title=v.param.title.replace(J,H));if(1==G.length){B=new RegExp(G[0]);J=-1<G.indexOf(r)?G.indexOf(r):!1;!1===J&&r.match(B)&&(J=0);if(!1===J)return J;if(v.method.toLowerCase()!==w)return!1;'undefined'==typeof wa[w]&&(wa[w]={});y=G[J].substring(1);J=v.requirements[y];if(/^\//.test(J))B=J.match(/\/(.*)\//).pop(),n=J.replace('/'+B+'/',''),B=(new RegExp(B,n)).test(H);else if(/^validator::/.test(J)&&H){n={};B={};z={};D='';r.replace(new RegExp('[^'+y+']','g'),function(pa){D+=
125
- pa});n[y]=H.replace(new RegExp(D,'g'),'');try{B=JSON.parse(J.split(/::/).splice(1)[0].replace(/([^:"\s+](\w+)):/g,'"$1":').replace(/([^:"\s+](\w+))\s+:/g,'"$1":'))}catch(pa){throw pa;}'undefined'!=typeof B.query&&'undefined'!=typeof B.query.data&&r==B.query.data[Object.keys(B.query.data)[0]]&&(B.query.data[Object.keys(B.query.data)[0]]=n[y],wa.params[y]=n[y]);z[y]=B;n=new R('routing',n,null,z);if(0==B.count())return console.error('Route validation failed '+v.rule),!1;for(var x in B)Array.isArray(B[x])?
126
- await n[y][x].apply(n[y],B[x]):await n[y][x](B[x],wa,Fa,T);B=n.isValid()}else B=(new RegExp(v.requirements[y])).test(H);if('undefined'!=typeof v.param[y]&&'undefined'!=typeof v.requirements&&'undefined'!=typeof v.requirements[y]&&'undefined'!=typeof wa.params&&B){wa.params[y]=H;if('undefined'==typeof wa[w][y]){switch(H){case 'null':H=null;break;case 'false':H=!1;break;case 'true':H=!0}wa[w][y]=H}return!0}}else{Fa=v.url;T=wa.url;w={};z='';var E=!1,O=0;x=0;for(var U=T.length;x<U;++x)if(T.charAt(x)!=
127
- Fa.charAt(O)||E){if(''==z)E=!0,z+=T.charAt(x);else if(x>Fa.indexOf(G[0])+G[0].length){J=v.requirements[G[0]];H=z.substring(0,z.length);if(/^\//.test(J))B=J.match(/\/(.*)\//).pop(),n=J.replace('/'+B+'/',''),B=(new RegExp(B,n)).test(H);else if(/^validator::/.test(J)){n={};B={};z={};D='';r.replace(new RegExp('[^'+y[0]+']','g'),function(pa){D+=pa});n[y[0]]=H.replace(new RegExp(D,'g'),'');B=JSON.parse(J.split(/::/).splice(1)[0].replace(/([^\W+ true false])+(\w+)/g,'"$&"'));z[y[0]]=B;n=new R('routing',
128
- n,null,z);for(let pa in B)if(Array.isArray(B[pa]))n[y[0]][pa].apply(n[y[0]],B[pa]);else n[y[0]][pa](B[pa]);B=n.isValid()}else B=(new RegExp(v.requirements[y[0]])).test(H);if(B)w[G[0].substring(1)]=H;else return!1;z='';E=!1;O=Fa.indexOf(G[0])+G[0].length;--x;G.splice(0,1)}else z+=T.charAt(x),++O;if(x==U-1)if(J=v.requirements[G[0]],H=z.substring(0,z.length),/^\//.test(J)?(B=J.match(/\/(.*)\//).pop(),n=J.replace('/'+B+'/',''),B=(new RegExp(B,n)).test(H)):B=(new RegExp(v.requirements[y])).test(H),B)w[G[0].substring(1)]=
129
- H;else return!1}else++O;if(w.count()==G.length){y=null;for(y in w){switch(w[y]){case 'null':w[y]=null;break;case 'false':w[y]=!1;break;case 'true':w[y]=!0}wa.params[y]=w[y]}return!0}}return!1},Q=function(r){return/\/$/.test(r)?Q.variable+'/':Q.variable},S=function(r,H){var v=null,wa,Fa=r.url,T=null;for(T in r.param)if(('undefined'==typeof H||'undefined'!=typeof H[T])&&/^:/.test(r.param[T])){var J=r.param[T].substring(1);if('undefined'!=typeof H&&'undefined'!=typeof H[J]){var G=new RegExp('(:'+J+'/|:'+
130
- J+'$)','g');'undefined'!=typeof r.param.path&&/:/.test(r.param.path)&&(r.param.path=r.param.path.replace(G,H[J]));'undefined'!=typeof r.param.title&&/:/.test(r.param.title)&&(r.param.title=r.param.title.replace(G,H[J]));'undefined'!=typeof r.param.namespace&&/:/.test(r.param.namespace)&&(r.param.namespace=r.param.namespace.replace(G,H[J]));'undefined'!=typeof r.param.file&&/:/.test(r.param.file)&&(Q.variable=H[J],r.param.file=r.param.file.replace(G,Q));if(/,/.test(r.url)){v=r.url.split(/,/g);var B=
131
- 0;for(wa=v.length;B<wa;++B)Q.variable=H[J],v[B]=v[B].replace(G,Q);r.url=v.join(',')}else Q.variable=H[J],r.url=r.url.replace(G,Q)}}if(v){B=0;wa=v.length;Fa=Fa.split(/,/g);var n=0;for(r.urlIndex=0;B<wa;++B)if(v=0,G=Fa[0].match(/:[-_a-z0-9]+/ig)){T=0;for(J=G.length;T<J;T++){var y=G[T].substring(1);'undefined'!=typeof H[y]&&H[y]&&v++}v>n&&(n=v,r.urlIndex=B)}}return r};P.getRoute=function(r,H,v){var wa=null,Fa=!1;A?(window.location.port||window.location.hostname!=window.gina.config.hostname.replace(/^(https|http|wss|ws):\/\//,
132
- '').replace(/:\d+$/,'')||(Fa=!0,window.gina.config.hostname=window.gina.config.hostname.replace(/^(https|http|wss|ws):\/\//,'').replace(/:\d+$/,'')),wa=window.gina.config):(wa=getContext('gina').config,'undefined'!=typeof getContext('argvFilename')&&(wa.getRouting=getContext('gina').Config.instance.getRouting),Fa=getContext('isProxyHost'));var T=wa.env||GINA_ENV,J=null,G=wa.bundle;/@/.test(r)||'undefined'==typeof G||null==G||(r=r.toLowerCase(),r+='@'+G);if(/@/.test(r)){var B=r.replace(/(.*):\/\//,
133
- '').split(/@/);G=B[1];/\/(.*)$/.test(r)&&(J=r.replace(/(.*):\/\//,'').split(/\/(.*)$/)[1],G=G.replace(/\/(.*)$/,''),T=J||T);r=B[0].toLowerCase()+'@'+G}G=wa.getRouting(G,T);if('undefined'==typeof G[r])throw Error('[ RoutingHelper::getRouting(rule, params) ] : `'+r+'` not found !');J=JSON.clone(G[r]);B=null;J=S(J,H);(J.isProxyHost=Fa)?(J.proxy_hostname=A?window.location.protocol+'//'+document.location.hostname:process.gina.PROXY_HOSTNAME||wa.envConf._proxyHostname,J.proxy_host=J.proxy_hostname.replace(/^(https|http):\/\//,
134
- '')):A||'undefined'==typeof process.gina.PROXY_HOSTNAME||(J.proxy_hostname=process.gina.PROXY_HOSTNAME,J.proxy_host=J.proxy_hostname.replace(/^(https|http):\/\//,''),console.debug('[getRoute#2]['+Fa+'] process.gina.PROXY_HOSTNAME ('+process.gina.PROXY_HOSTNAME+') VS config.envConf._proxyHostname ('+wa.envConf._proxyHostname+')'));/,/.test(J.url)&&('undefined'!=typeof J.urlIndex&&(v=J.urlIndex,delete J.urlIndex),v='undefined'!=typeof v?v:0,J.url=J.url.split(/,/g)[v]);/\/$/.test(J.url)&&'/'!=J.url&&
135
- (J.url=J.url.substring(0,J.url.length-1));if(/GET/i.test(J.method)&&'undefined'!=typeof H){v='?';wa=G[r].url;Fa=[];G=0;for(let n in J.param)-1<P.reservedParams.indexOf(n)||(new RegExp(J.param[n])).test(wa)||'undefined'==typeof H[n]||(v+=n+'='+encodeRFC5987ValueChars(H[n])+'&',Fa[G]=H[n],++G);for(let n in H)-1<P.reservedParams.indexOf(n)||'undefined'!=typeof J.requirements[n]||-1<Fa.indexOf(n)||(v='object'==typeof H[n]?v+(n+'='+encodeRFC5987ValueChars(JSON.stringify(H[n]))+'&'):v+(n+'='+H[n]+'&'));
136
- G=Fa=wa=null;1<v.length&&(v=v.substring(0,v.length-1),J.url+=v);v=null}J.toUrl=function(n){var y=null;/^redirect$/i.test(this.param.control)&&(y=P.getUrlProps(this.bundle,T||GINA_ENV));var z=this.webroot||y.webroot;y=''+this.hostname||''+y.hostname;var D=''+this.url;this.isProxyHost&&(y=''+this.proxy_hostname);this.url='undefined'!=typeof n&&/^true$/i.test(n)?D.replace(new RegExp('^'+z),'/'):D.replace(new RegExp('^('+z+'|/$)'),z);return y+this.url};J.request=function(n,y){var z=null,D=null;'function'==
137
- typeof arguments[arguments.length-1]&&(z=arguments[arguments.length-1]);'object'==typeof arguments[2]&&(D=arguments[2]);var w=this.webroot||D.webroot,x=this.hostname||D.hostname;D='undefined'!=typeof n&&1==n?path.replace(w,'/'):this.url||D.url;/^\//.test(D)&&(D=x+D);x=/^https/.test(x)?'https':'http';A?window.open(D,'undefined'!=typeof y&&'undefined'!=typeof y.target?y.target:'_self'):('undefined'==typeof y.agent&&(y.agent=!1),x=require(''+x),w=function(E){var O='',U=!1;E.on('data',function(pa){O+=
138
- pa});E.on('error',function(pa){U='Failed to get mail content';pa&&'undefined'!=typeof pa.stack?U+=pa.stack:'string'==typeof pa&&(U+='\n'+pa)});E.on('end',function(){if(/^\{/.test(O))try{O=JSON.parse(O),'undefined'!=typeof O.error&&(U=JSON.clone(O),O=null)}catch(pa){U=pa}U?z(U):z(!1,O)})},z?x.get(D,y,w):x.get(D,y))};!/:/.test(J.url)||/:d+\//.test(J.url)||/:\/\//.test(J.url)||(H=J.url.match(/(:(.*)\/|:(.*)$)/g).map(function(n){return n.replace(/\//g,'')}).join(', '),B='[ RoutingHelper::getRoute(rule[, bundle, method]) ] : route [ %r ] param placeholder not defined: `'+
139
- J.url+'` !\n Check your route description to compare requirements against param variables [ '+H+']',B=B.replace(/%r/,r),r=Error(B),console.warn(r),B=r=H=null);return J};P.getRouteByUrl=function(r,H,v,wa,Fa){2==arguments.length&&'undefined'!=typeof arguments[1]&&arguments[1]&&-1<P.allowedMethods.indexOf(arguments[1].toLowerCase())&&(v=arguments[1],H=void 0);var T=null,J=null,G=null,B=null,n=null,y=null;if(/#/.test(r)&&1<r.length){var z=r.split(/#/);r=z[0];n='#'+z[1];z=null}1==arguments.length&&'undefined'!=
140
- typeof arguments[0]&&(/^(https|http)/i.test(r)||/^\//.test(r)||(r='/'+r),T='/'+r.split(/\//g)[1],A&&(B=gina.config.reverseRouting,G=gina.config.routing),'undefined'!=typeof B[T]&&(z=G[B[T]],H=z.bundle,T=z.webroot,y=z.hostname,z=null));Fa='boolean'!=typeof arguments[arguments.length-1]?!1:arguments[arguments.length-1];var D=!1,w=null,x=B=w=B=null;z='undefined'!=typeof v?!0:!1;A?(w=window.gina.config,H='undefined'!=typeof H?H:w.bundle,B=w.env,G=w.routing||w.getRouting(H),B=w.reverseRouting,isXMLRequest=
141
- 'undefined'!=typeof isXMLRequest?isXMLRequest:!1,y=y||w.hostname,T=T||w.webroot,wa={routing:{},method:v,params:{},url:r},H&&(wa.bundle=H)):(w=getContext('gina').config,H='undefined'!=typeof H?H:w.bundle,B=w.env,G=w.getRouting(H),y=w.envConf[H][B].hostname,T=w.envConf[H][B].server.webroot,wa||={routing:{},isXMLRequest:!1,method:'undefined'!=typeof v?v.toLowerCase():'get',params:{},url:r},Fa&&(wa.method=v),isXMLRequest=wa.isXMLRequest||!1);w=r.replace(new RegExp('^('+y+'|'+y.replace(/:\d+/,'')+')'),
142
- '');'undefined'==typeof wa.routing.path&&(wa.routing.path=decodeURI(w));v='undefined'!=typeof v?v.toLowerCase():'get';z&&(wa.originalMethod=wa.method,wa.method=v,wa.routing.path=decodeURI(w));wa.method||(wa.method=v);B={};T=new RegExp(v,'i');y=null;for(E in G){if('undefined'==typeof G[E].param)break;if(G[E].bundle==H&&(y=G[E].method,/,/.test(y)&&T.test(y)&&(y=wa.method),'undefined'==typeof G[E].method||T.test(y))){B={method:y,requirements:G[E].requirements,namespace:G[E].namespace||void 0,url:decodeURI(w),
143
- rule:G[E].originalRule||E,param:G[E].param,middleware:JSON.clone(G[E].middleware),bundle:G[E].bundle,isXMLRequest};try{if(x=P.compareUrls(B,G[E].url,wa),x.past){J=JSON.clone(G[E]);J.name=E;D=!0;x={};break}}catch(O){throw Error('Route [ '+E+' ] needs your attention.\n'+O.stack);}}}if(D)return/\/$/.test(r)&&'/'!=r&&(r=r.substring(0,r.length-1)),n&&(r+=n),J.url=r,J.toUrl=function(O){var U=this.webroot,pa=this.hostname,Ea=this.url;this.url='undefined'!=typeof O&&1==O?Ea.replace(U,'/'):Ea;return pa+this.url},
144
- J;if(A){var E=!1;if('#'==r&&/GET/i.test(v)&&z||/^404:/.test(r))r=location.pathname,E=!0;'undefined'==typeof P.notFound&&(P.notFound={});n=null;J='[ RoutingHelper::getRouteByUrl(rule[, bundle, method]) ] : route [ %r ] is called but not found inside your view: `'+r+'` !';if((n=(n=gina.hasPopinHandler&&gina.popinIsBinded?gina.popin.getActivePopin().target.innerHTML.match(/404:\[\w+\][a-z 0-9-_@]+/):document.body.innerHTML.match(/404:\[\w+\][a-z 0-9-_@]+/))&&0<n.length?n[0]:null)&&z&&E)return E=n.match(/\[\w+\]/)[0],
145
- n=n.replace('404:'+E,E.replace(/\[|\]/g,'')+'::'),J=J.replace(/%r/,n.replace(/404:\s+/,'')),'undefined'==typeof P.notFound[n]?P.notFound[n]={count:1,message:J}:z&&'undefined'!=typeof P.notFound[n]&&++P.notFound[n].count,!1;if((E=gina.config.reverseRouting[r]||null)&&'undefined'!=typeof E&&E.split(/@(.+)$/)[1]==H)return n=E,'undefined'==typeof P.notFound[n]?(J=J.replace(/%r/,v.toUpperCase()+'::'+E),P.notFound[n]={count:1,message:J}):z&&'undefined'!=typeof P.notFound[n]&&++P.notFound[n].count,!1;n=
146
- P.compareUrls(B,r,wa)||null;n.past&&z&&(n=v.toUpperCase()+'::'+n.request.routing.rule,'undefined'==typeof P.notFound[n]?J=J.replace(/%r/,n):++P.notFound[n].count);return!1}console.warn(Error('[ RoutingHelper::getRouteByUrl(rule[, bundle, method, request]) ] : route not found for url: `'+r+'` !').stack);return!1};return P}
116
+ (5E3<=Routing._cached.length&&P.invalidateCached(Routing._cached[0]),Routing._cached.push(r),Routing._cachedRoutes[r]={name:H,routing:v,params:wa,methodParams:Fa})};P.getCached=function(r,H){if(-1<Routing._cached.indexOf(r)){var v=Routing._cachedRoutes[r],wa=H.method.toLowerCase();r=JSON.clone(v.routing);v={method:wa,requirements:r.requirements,namespace:r.namespace||void 0,url:decodeURI(H.url),rule:r.originalRule||v.name,param:r.param,middleware:r.middleware,bundle:r.bundle,isXMLRequest:H.isXMLRequest,
117
+ isWithCredentials:H.isWithCredentials};'undefined'==typeof r.rule&&'undefined'!=typeof v.rule&&(r.rule=v.rule);'undefined'!=typeof r.cache&&(v.cache=r.cache);'undefined'!=typeof r.queryTimeout&&(v.queryTimeout=parseTimeout(r.queryTimeout));return P.compareUrls(v,r.url,H)}return null};P.invalidateCached=function(r){-1<Routing._cached.indexOf(r)&&(Routing._cached.splice(Routing._cached.indexOf(r),1),delete Routing._cachedRoutes[r])};P.compareUrls=async function(r,H,v,wa,Fa){'undefined'==typeof v&&(v=
118
+ {routing:{}});if(/,/.test(H)){var T=0;H=H.split(/,/g);for(var J=H.length,G={past:!1,request:v};T<J&&!G.past;)G=await N(r,H[T],v,wa,Fa),++T;return G}return await N(r,H,v,wa,Fa)};var N=async function(r,H,v,wa,Fa){var T=null;try{T=r.url.split(/\//)}catch(U){console.warn(U),T=['']}H=H.split(/\//);var J=0,G=0,B=H.length,n=0,y={},z=0,D=v.method.toLowerCase(),w='get';try{w=r.method.toLowerCase()}catch(U){}var x=!1;if('undefined'!=typeof r.requirements&&/get|delete/i.test(D)&&'undefined'!=typeof v[D]||'undefined'!=
119
+ typeof r.requirements&&/get/i.test(D)&&/delete/i.test(w)){/get/i.test(D)&&/delete/i.test(w)&&(D=w);if(/^(delete)$/i.test(D)&&T.length===H.length){'undefined'==typeof v[D]&&(v[D]={});for(let U=0,pa=H.length;U<pa;U++)if(T[U]===H[U])++n;else if(w=H[U].substring(1),'undefined'!=typeof r.requirements[w]){w=r.requirements[w];if(/^\//.test(w))w=w.substring(1,w.lastIndexOf('/')-1);else if(/^validator::/.test(w)&&await ha(H[U],T[U],r,v,wa,Fa)){++n;continue}/^:/.test(H[U])&&'undefined'!=typeof w&&(new RegExp(w)).test(T[U])&&
120
+ (++n,v[D][H[U].substring(1)]=T[U])}x=!0}for(var E in v[D])'undefined'!=typeof r.requirements[E]&&0>H.indexOf(':'+E)&&(H[G]=':'+E,++G,T[J]=v[D][E],++J,x||T.length!==H.length||++B)}if(!x&&T.length===H.length)for(;z<B;++z)T[z]===H[z]?++n:n==z&&/:/.test(H[z])&&await ha(H[z],T[z],r,v,wa,Fa)&&++n;if('undefined'!=typeof r.requirements&&D==r.method.toLowerCase()&&!x&&n>=B)for(E=Object.getOwnPropertyNames(r.requirements),J=0,H.join(',').match(/:[-_a-z0-9]+/g);J<E.length;){G=E[J];if('undefined'==typeof r.param[G]&&
121
+ /^validator::/i.test(r.requirements[G])){if(H.length!=T.length)break;var O=H.join(',').match(/:[-_a-z0-9]+/g);let U=r.requirements[G];z={};w={};x={};try{w=JSON.parse(U.split(/::/).splice(1)[0].replace(/([^:"\s+](\w+)):/g,'"$1":').replace(/([^:"\s+](\w+))\s+:/g,'"$1":'))}catch(pa){throw pa;}if('undefined'!=typeof w.query&&'undefined'!=typeof w.query.data){z=w.query.data;for(let pa in z)0>O.indexOf(z[pa])&&delete z[pa];for(let pa=0,Ea=H.length;pa<Ea;pa++)/^:/.test(H[pa])&&(O=H[pa].replace(/^:/,''),
122
+ ''!=O&&'undefined'!=typeof T[pa]&&(z[O]=T[pa],'undefined'==typeof v.params[O]&&(v.params[O]=T[pa])))}z=ja(z,JSON.clone(v[D])||{});'undefined'==typeof z[G]&&(z[G]=null);x[G]=w;_validator=A?new R(z):new R('routing',z,null,x);if(0==w.count()){console.error('Route validation failed '+r.rule);--n;J++;continue}for(let pa in w)if('undefined'!=typeof w[pa].data&&(w[pa].data=z),x=Array.isArray(w[pa])?await _validator[G][pa].apply(_validator[G],w[pa]):await _validator[G][pa](w[pa],v,wa,Fa),!x.isValid&&(--n,
123
+ 'undefined'!=typeof x.error))throw x.error;}J++}y.past=n===B?!0:!1;y.past&&(v.routing=S(r,v[D]),y.request=v);return y},ha=async function(r,H,v,wa,Fa,T){var J=-1,G=r.match(/:\w+/g);J=new RegExp(r,'g');var B=null,n=null,y=null;B=!1;var z=B=n=n=null,D=null,w=wa.method.toLowerCase();if(!G.length)return!1;v.param.path&&J.test(v.param.path)&&(v.param.path=v.param.path.replace(J,H));v.param.namespace&&J.test(v.param.namespace)&&(v.param.namespace=v.param.namespace.replace(J,H));'undefined'!=typeof v.param.file&&
124
+ /:/.test(v.param.file)&&(B=new RegExp('(:'+r+'/|:'+r+'$)','g'),Q.variable=H,v.param.file=v.param.file.replace(B,Q),B=null);v.param.title&&J.test(v.param.title)&&(v.param.title=v.param.title.replace(J,H));if(1==G.length){B=new RegExp(G[0]);J=-1<G.indexOf(r)?G.indexOf(r):!1;!1===J&&r.match(B)&&(J=0);if(!1===J)return J;if(v.method.toLowerCase()!==w)return!1;'undefined'==typeof wa[w]&&(wa[w]={});y=G[J].substring(1);J=v.requirements[y];if(/^\//.test(J))B=J.match(/\/(.*)\//).pop(),n=J.replace('/'+B+'/',
125
+ ''),B=(new RegExp(B,n)).test(H);else if(/^validator::/.test(J)&&H){n={};B={};z={};D='';r.replace(new RegExp('[^'+y+']','g'),function(pa){D+=pa});n[y]=H.replace(new RegExp(D,'g'),'');try{B=JSON.parse(J.split(/::/).splice(1)[0].replace(/([^:"\s+](\w+)):/g,'"$1":').replace(/([^:"\s+](\w+))\s+:/g,'"$1":'))}catch(pa){throw pa;}'undefined'!=typeof B.query&&'undefined'!=typeof B.query.data&&r==B.query.data[Object.keys(B.query.data)[0]]&&(B.query.data[Object.keys(B.query.data)[0]]=n[y],wa.params[y]=n[y]);
126
+ z[y]=B;n=new R('routing',n,null,z);if(0==B.count())return console.error('Route validation failed '+v.rule),!1;for(var x in B)Array.isArray(B[x])?await n[y][x].apply(n[y],B[x]):await n[y][x](B[x],wa,Fa,T);B=n.isValid()}else B=(new RegExp(v.requirements[y])).test(H);if('undefined'!=typeof v.param[y]&&'undefined'!=typeof v.requirements&&'undefined'!=typeof v.requirements[y]&&'undefined'!=typeof wa.params&&B){wa.params[y]=H;if('undefined'==typeof wa[w][y]){switch(H){case 'null':H=null;break;case 'false':H=
127
+ !1;break;case 'true':H=!0}wa[w][y]=H}return!0}}else{Fa=v.url;T=wa.url;w={};z='';var E=!1,O=0;x=0;for(var U=T.length;x<U;++x)if(T.charAt(x)!=Fa.charAt(O)||E){if(''==z)E=!0,z+=T.charAt(x);else if(x>Fa.indexOf(G[0])+G[0].length){J=v.requirements[G[0]];H=z.substring(0,z.length);if(/^\//.test(J))B=J.match(/\/(.*)\//).pop(),n=J.replace('/'+B+'/',''),B=(new RegExp(B,n)).test(H);else if(/^validator::/.test(J)){n={};B={};z={};D='';r.replace(new RegExp('[^'+y[0]+']','g'),function(pa){D+=pa});n[y[0]]=H.replace(new RegExp(D,
128
+ 'g'),'');B=JSON.parse(J.split(/::/).splice(1)[0].replace(/([^\W+ true false])+(\w+)/g,'"$&"'));z[y[0]]=B;n=new R('routing',n,null,z);for(let pa in B)if(Array.isArray(B[pa]))n[y[0]][pa].apply(n[y[0]],B[pa]);else n[y[0]][pa](B[pa]);B=n.isValid()}else B=(new RegExp(v.requirements[y[0]])).test(H);if(B)w[G[0].substring(1)]=H;else return!1;z='';E=!1;O=Fa.indexOf(G[0])+G[0].length;--x;G.splice(0,1)}else z+=T.charAt(x),++O;if(x==U-1)if(J=v.requirements[G[0]],H=z.substring(0,z.length),/^\//.test(J)?(B=J.match(/\/(.*)\//).pop(),
129
+ n=J.replace('/'+B+'/',''),B=(new RegExp(B,n)).test(H)):B=(new RegExp(v.requirements[y])).test(H),B)w[G[0].substring(1)]=H;else return!1}else++O;if(w.count()==G.length){y=null;for(y in w){switch(w[y]){case 'null':w[y]=null;break;case 'false':w[y]=!1;break;case 'true':w[y]=!0}wa.params[y]=w[y]}return!0}}return!1},Q=function(r){return/\/$/.test(r)?Q.variable+'/':Q.variable},S=function(r,H){var v=null,wa,Fa=r.url,T=null;for(T in r.param)if(('undefined'==typeof H||'undefined'!=typeof H[T])&&/^:/.test(r.param[T])){var J=
130
+ r.param[T].substring(1);if('undefined'!=typeof H&&'undefined'!=typeof H[J]){var G=new RegExp('(:'+J+'/|:'+J+'$)','g');'undefined'!=typeof r.param.path&&/:/.test(r.param.path)&&(r.param.path=r.param.path.replace(G,H[J]));'undefined'!=typeof r.param.title&&/:/.test(r.param.title)&&(r.param.title=r.param.title.replace(G,H[J]));'undefined'!=typeof r.param.namespace&&/:/.test(r.param.namespace)&&(r.param.namespace=r.param.namespace.replace(G,H[J]));'undefined'!=typeof r.param.file&&/:/.test(r.param.file)&&
131
+ (Q.variable=H[J],r.param.file=r.param.file.replace(G,Q));if(/,/.test(r.url)){v=r.url.split(/,/g);var B=0;for(wa=v.length;B<wa;++B)Q.variable=H[J],v[B]=v[B].replace(G,Q);r.url=v.join(',')}else Q.variable=H[J],r.url=r.url.replace(G,Q)}}if(v){B=0;wa=v.length;Fa=Fa.split(/,/g);var n=0;for(r.urlIndex=0;B<wa;++B)if(v=0,G=Fa[0].match(/:[-_a-z0-9]+/ig)){T=0;for(J=G.length;T<J;T++){var y=G[T].substring(1);'undefined'!=typeof H[y]&&H[y]&&v++}v>n&&(n=v,r.urlIndex=B)}}return r};P.getRoute=function(r,H,v){var wa=
132
+ null,Fa=!1;A?(window.location.port||window.location.hostname!=window.gina.config.hostname.replace(/^(https|http|wss|ws):\/\//,'').replace(/:\d+$/,'')||(Fa=!0,window.gina.config.hostname=window.gina.config.hostname.replace(/^(https|http|wss|ws):\/\//,'').replace(/:\d+$/,'')),wa=window.gina.config):(wa=getContext('gina').config,'undefined'!=typeof getContext('argvFilename')&&(wa.getRouting=getContext('gina').Config.instance.getRouting),Fa=getContext('isProxyHost'));var T=wa.env||GINA_ENV,J=null,G=wa.bundle;
133
+ /@/.test(r)||'undefined'==typeof G||null==G||(r=r.toLowerCase(),r+='@'+G);if(/@/.test(r)){var B=r.replace(/(.*):\/\//,'').split(/@/);G=B[1];/\/(.*)$/.test(r)&&(J=r.replace(/(.*):\/\//,'').split(/\/(.*)$/)[1],G=G.replace(/\/(.*)$/,''),T=J||T);r=B[0].toLowerCase()+'@'+G}G=wa.getRouting(G,T);if('undefined'==typeof G[r])throw Error('[ RoutingHelper::getRouting(rule, params) ] : `'+r+'` not found !');J=JSON.clone(G[r]);B=null;J=S(J,H);(J.isProxyHost=Fa)?(J.proxy_hostname=A?window.location.protocol+'//'+
134
+ document.location.hostname:process.gina.PROXY_HOSTNAME||wa.envConf._proxyHostname,J.proxy_host=J.proxy_hostname.replace(/^(https|http):\/\//,'')):A||'undefined'==typeof process.gina.PROXY_HOSTNAME||(J.proxy_hostname=process.gina.PROXY_HOSTNAME,J.proxy_host=J.proxy_hostname.replace(/^(https|http):\/\//,''),console.debug('[getRoute#2]['+Fa+'] process.gina.PROXY_HOSTNAME ('+process.gina.PROXY_HOSTNAME+') VS config.envConf._proxyHostname ('+wa.envConf._proxyHostname+')'));/,/.test(J.url)&&('undefined'!=
135
+ typeof J.urlIndex&&(v=J.urlIndex,delete J.urlIndex),v='undefined'!=typeof v?v:0,J.url=J.url.split(/,/g)[v]);/\/$/.test(J.url)&&'/'!=J.url&&(J.url=J.url.substring(0,J.url.length-1));if(/GET/i.test(J.method)&&'undefined'!=typeof H){v='?';wa=G[r].url;Fa=[];G=0;for(let n in J.param)-1<P.reservedParams.indexOf(n)||(new RegExp(J.param[n])).test(wa)||'undefined'==typeof H[n]||(v+=n+'='+encodeRFC5987ValueChars(H[n])+'&',Fa[G]=H[n],++G);for(let n in H)-1<P.reservedParams.indexOf(n)||'undefined'!=typeof J.requirements[n]||
136
+ -1<Fa.indexOf(n)||(v='object'==typeof H[n]?v+(n+'='+encodeRFC5987ValueChars(JSON.stringify(H[n]))+'&'):v+(n+'='+H[n]+'&'));G=Fa=wa=null;1<v.length&&(v=v.substring(0,v.length-1),J.url+=v);v=null}J.toUrl=function(n){var y=null;/^redirect$/i.test(this.param.control)&&(y=P.getUrlProps(this.bundle,T||GINA_ENV));var z=this.webroot||y.webroot;y=''+this.hostname||''+y.hostname;var D=''+this.url;this.isProxyHost&&(y=''+this.proxy_hostname);this.url='undefined'!=typeof n&&/^true$/i.test(n)?D.replace(new RegExp('^'+
137
+ z),'/'):D.replace(new RegExp('^('+z+'|/$)'),z);return y+this.url};J.request=function(n,y){var z=null,D=null;'function'==typeof arguments[arguments.length-1]&&(z=arguments[arguments.length-1]);'object'==typeof arguments[2]&&(D=arguments[2]);var w=this.webroot||D.webroot,x=this.hostname||D.hostname;D='undefined'!=typeof n&&1==n?path.replace(w,'/'):this.url||D.url;/^\//.test(D)&&(D=x+D);x=/^https/.test(x)?'https':'http';A?window.open(D,'undefined'!=typeof y&&'undefined'!=typeof y.target?y.target:'_self'):
138
+ ('undefined'==typeof y.agent&&(y.agent=!1),x=require(''+x),w=function(E){var O='',U=!1;E.on('data',function(pa){O+=pa});E.on('error',function(pa){U='Failed to get mail content';pa&&'undefined'!=typeof pa.stack?U+=pa.stack:'string'==typeof pa&&(U+='\n'+pa)});E.on('end',function(){if(/^\{/.test(O))try{O=JSON.parse(O),'undefined'!=typeof O.error&&(U=JSON.clone(O),O=null)}catch(pa){U=pa}U?z(U):z(!1,O)})},z?x.get(D,y,w):x.get(D,y))};!/:/.test(J.url)||/:d+\//.test(J.url)||/:\/\//.test(J.url)||(H=J.url.match(/(:(.*)\/|:(.*)$)/g).map(function(n){return n.replace(/\//g,
139
+ '')}).join(', '),B='[ RoutingHelper::getRoute(rule[, bundle, method]) ] : route [ %r ] param placeholder not defined: `'+J.url+'` !\n Check your route description to compare requirements against param variables [ '+H+']',B=B.replace(/%r/,r),r=Error(B),console.warn(r),B=r=H=null);return J};P.getRouteByUrl=function(r,H,v,wa,Fa){2==arguments.length&&'undefined'!=typeof arguments[1]&&arguments[1]&&-1<P.allowedMethods.indexOf(arguments[1].toLowerCase())&&(v=arguments[1],H=void 0);var T=null,J=null,G=null,
140
+ B=null,n=null,y=null;if(/#/.test(r)&&1<r.length){var z=r.split(/#/);r=z[0];n='#'+z[1];z=null}1==arguments.length&&'undefined'!=typeof arguments[0]&&(/^(https|http)/i.test(r)||/^\//.test(r)||(r='/'+r),T='/'+r.split(/\//g)[1],A&&(B=gina.config.reverseRouting,G=gina.config.routing),'undefined'!=typeof B[T]&&(z=G[B[T]],H=z.bundle,T=z.webroot,y=z.hostname,z=null));Fa='boolean'!=typeof arguments[arguments.length-1]?!1:arguments[arguments.length-1];var D=!1,w=null,x=B=w=B=null;z='undefined'!=typeof v?!0:
141
+ !1;A?(w=window.gina.config,H='undefined'!=typeof H?H:w.bundle,B=w.env,G=w.routing||w.getRouting(H),B=w.reverseRouting,isXMLRequest='undefined'!=typeof isXMLRequest?isXMLRequest:!1,y=y||w.hostname,T=T||w.webroot,wa={routing:{},method:v,params:{},url:r},H&&(wa.bundle=H)):(w=getContext('gina').config,H='undefined'!=typeof H?H:w.bundle,B=w.env,G=w.getRouting(H),y=w.envConf[H][B].hostname,T=w.envConf[H][B].server.webroot,wa||={routing:{},isXMLRequest:!1,method:'undefined'!=typeof v?v.toLowerCase():'get',
142
+ params:{},url:r},Fa&&(wa.method=v),isXMLRequest=wa.isXMLRequest||!1);w=r.replace(new RegExp('^('+y+'|'+y.replace(/:\d+/,'')+')'),'');'undefined'==typeof wa.routing.path&&(wa.routing.path=decodeURI(w));v='undefined'!=typeof v?v.toLowerCase():'get';z&&(wa.originalMethod=wa.method,wa.method=v,wa.routing.path=decodeURI(w));wa.method||(wa.method=v);B={};T=new RegExp(v,'i');y=null;for(E in G){if('undefined'==typeof G[E].param)break;if(G[E].bundle==H&&(y=G[E].method,/,/.test(y)&&T.test(y)&&(y=wa.method),
143
+ 'undefined'==typeof G[E].method||T.test(y))){B={method:y,requirements:G[E].requirements,namespace:G[E].namespace||void 0,url:decodeURI(w),rule:G[E].originalRule||E,param:G[E].param,middleware:JSON.clone(G[E].middleware),bundle:G[E].bundle,isXMLRequest};try{if(x=P.compareUrls(B,G[E].url,wa),x.past){J=JSON.clone(G[E]);J.name=E;D=!0;x={};break}}catch(O){throw Error('Route [ '+E+' ] needs your attention.\n'+O.stack);}}}if(D)return/\/$/.test(r)&&'/'!=r&&(r=r.substring(0,r.length-1)),n&&(r+=n),J.url=r,
144
+ J.toUrl=function(O){var U=this.webroot,pa=this.hostname,Ea=this.url;this.url='undefined'!=typeof O&&1==O?Ea.replace(U,'/'):Ea;return pa+this.url},J;if(A){var E=!1;if('#'==r&&/GET/i.test(v)&&z||/^404:/.test(r))r=location.pathname,E=!0;'undefined'==typeof P.notFound&&(P.notFound={});n=null;J='[ RoutingHelper::getRouteByUrl(rule[, bundle, method]) ] : route [ %r ] is called but not found inside your view: `'+r+'` !';if((n=(n=gina.hasPopinHandler&&gina.popinIsBinded?gina.popin.getActivePopin().target.innerHTML.match(/404:\[\w+\][a-z 0-9-_@]+/):
145
+ document.body.innerHTML.match(/404:\[\w+\][a-z 0-9-_@]+/))&&0<n.length?n[0]:null)&&z&&E)return E=n.match(/\[\w+\]/)[0],n=n.replace('404:'+E,E.replace(/\[|\]/g,'')+'::'),J=J.replace(/%r/,n.replace(/404:\s+/,'')),'undefined'==typeof P.notFound[n]?P.notFound[n]={count:1,message:J}:z&&'undefined'!=typeof P.notFound[n]&&++P.notFound[n].count,!1;if((E=gina.config.reverseRouting[r]||null)&&'undefined'!=typeof E&&E.split(/@(.+)$/)[1]==H)return n=E,'undefined'==typeof P.notFound[n]?(J=J.replace(/%r/,v.toUpperCase()+
146
+ '::'+E),P.notFound[n]={count:1,message:J}):z&&'undefined'!=typeof P.notFound[n]&&++P.notFound[n].count,!1;n=P.compareUrls(B,r,wa)||null;n.past&&z&&(n=v.toUpperCase()+'::'+n.request.routing.rule,'undefined'==typeof P.notFound[n]?J=J.replace(/%r/,n):++P.notFound[n].count);return!1}console.warn(Error('[ RoutingHelper::getRouteByUrl(rule[, bundle, method, request]) ] : route not found for url: `'+r+'` !').stack);return!1};return P}
147
147
  'undefined'!==typeof module&&module.exports?('undefined'==typeof console.err&&(console=require('../../logger')),module.exports=Routing()):'function'===typeof define&&define.amd&&define('lib/routing',['require','lib/form-validator','lib/merge'],function(){return Routing()});function registerEvents(A,P){'undefined'==typeof gina&&'undefined'!=typeof window.gina&&(gina=window.gina);gina.registeredEvents[A]=P}function mergeEventProps(A,P){for(let V in P)'undefined'==typeof A[V]&&(A[V]=P[V]);return A}
148
148
  function addListener(A,P,V,ja){var R=function(Q,S,r,H){'undefined'!=typeof Q.event&&Q.event.isTouchSupported&&/^(click|mouseout|mouseover)/.test(r)&&-1==Q.event[r].indexOf(S)&&(Q.event[r][Q.event[r].length]=S);'undefined'!=typeof S&&null!=S?S.addEventListener?S.addEventListener(r,H,!1):S.attachEvent&&S.attachEvent('on'+r,H):Q.customEvent.addListener(r,H);gina.events[r]='undefined'!=typeof S.id&&'object'!=typeof S.id?S.id:S.getAttribute('id')},N=0,ha=null;if(Array.isArray(V))for(ha=V.length;N<ha;N++)R(A,
149
149
  P,V[N],ja);else if(Array.isArray(P))for(N=0,ha=P.length;N<ha;N++){let Q=/\.$/.test(V)?V+P[N].id:V;R(A,P[N],Q,ja)}else V=/\.$/.test(V)?V+P.id:V,R(A,P,V,ja)}
@@ -2547,10 +2547,12 @@ function Config(opt, contextResetNeeded) {
2547
2547
  }
2548
2548
 
2549
2549
  }
2550
+
2551
+ // Sort by descending length so more-specific paths are matched before the
2552
+ // catch-all root `/` entry in server.js handleStatics prefix-regex loop.
2553
+ conf[bundle][env].staticResources.sort(function(a, b) { return b.length - a.length; });
2550
2554
  }
2551
2555
 
2552
- console.warn('['+bundle+'/'+env+']files:', files);
2553
- console.warn('['+bundle+'/'+env+']reps:', JSON.stringify(reps, null, 2));
2554
2556
  files = whisper(reps, files);
2555
2557
 
2556
2558
  if (hasViews) {
@@ -795,42 +795,109 @@ function Couchbase(conn, infos) {
795
795
  }
796
796
  } //EO register
797
797
 
798
- var _proto = {
799
- onComplete : function(cb) {
800
- // console.warn('onComplete trigger: ', trigger, self._isRegisteredFromProto);
798
+ // ─────────────────────────────────────────────────────────────
799
+ // Option B — native Promise return (2026-03-20)
800
+ //
801
+ // Why: N1QL methods previously returned a plain _proto object
802
+ // { onComplete: fn }. This made them:
803
+ // • not directly awaitable — `await entity.method()` resolved
804
+ // to the _proto object, not the query result
805
+ // • fragile with util.promisify — promisify injects a trailing
806
+ // callback, caught here via the _mainCallback detection, but
807
+ // losing `this` context made certain methods hang silently
808
+ //
809
+ // What changed: when no _mainCallback is present we now return
810
+ // a native Promise instead of _proto. The Promise resolves
811
+ // with `data` (rows) so `await entity.method(args)` works
812
+ // directly — V8 native fast path, zero extra microtask hops.
813
+ //
814
+ // `.onComplete(cb)` is attached to the Promise so ALL
815
+ // existing callers keep working unchanged:
816
+ // entity.method(args).onComplete(function(err, data, meta) {...})
817
+ //
818
+ // meta is captured alongside data so .onComplete() callbacks
819
+ // receive the original (err, data, meta) signature unchanged.
820
+ //
821
+ // The query executes exactly once — register() is called with
822
+ // _internalCb in the setTimeout(0), same deferred-execution
823
+ // timing as before. .onComplete() chains on the resolved
824
+ // Promise instead of calling register() again.
825
+ //
826
+ // The _mainCallback path (util.promisify / explicit callback) is
827
+ // unchanged — register() is still called synchronously.
828
+ // ─────────────────────────────────────────────────────────────
829
+
830
+ if ( _mainCallback == null ) {
831
+
832
+ var _resolve, _reject, _internalData, _internalMeta;
833
+
834
+ var _promise = new Promise(function(resolve, reject) {
835
+ _resolve = resolve;
836
+ _reject = reject;
837
+ });
838
+
839
+ // Internal callback fed to register() — resolves/rejects
840
+ // the Promise and captures meta for .onComplete() callers.
841
+ var _internalCb = function(err, data, meta) {
842
+ if (err) {
843
+ _reject(err);
844
+ } else {
845
+ _internalData = data;
846
+ _internalMeta = meta;
847
+ _resolve(data);
848
+ }
849
+ };
850
+
851
+ // Backward-compatible .onComplete(cb):
852
+ // chains on the Promise resolution so the callback
853
+ // receives (err, data, meta) exactly as before.
854
+ _promise.onComplete = function(cb) {
855
+ _promise.then(
856
+ function() { cb(null, _internalData, _internalMeta); },
857
+ function(err) { cb(err); }
858
+ );
859
+ return _promise; // preserve chaining
860
+ };
861
+
862
+ // Trigger the query via the existing setTimeout(0) mechanism.
863
+ // Preserves original timing: .onComplete() and await both
864
+ // have time to set up before the query fires.
865
+ //
866
+ // _isRegisteredFromProto guard is intentionally REMOVED here.
867
+ //
868
+ // Background: the old _proto.onComplete() called register()
869
+ // synchronously, so the guard prevented accidental double-
870
+ // registration if .onComplete() was called more than once.
871
+ //
872
+ // With Option B, .onComplete() only chains on the Promise — it
873
+ // never calls register(). So there is no double-registration
874
+ // risk. More importantly, _isRegisteredFromProto is a shared
875
+ // flag on `self` (the connector entity). When a _mainCallback-
876
+ // path call (e.g. util.promisify) sets the flag to true, any
877
+ // *subsequent* Promise-path call on the SAME entity would see
878
+ // the flag set and skip register() — silently dropping the N1QL
879
+ // query and hanging the await forever.
880
+ //
881
+ // Example that broke: inside account.entity.delete, the call
882
+ // promisify(db.accountEntity.getOneByIdAndJwtLogin)() runs first
883
+ // (sets _isRegisteredFromProto=true via register()), then
884
+ // await db.accountEntity.getAllOwnedCompaniesIds() (Promise path)
885
+ // hit the guard and skipped register() — query never fired.
886
+ setTimeout(function() {
801
887
  if ( sdkVersion > 2 ) {
802
- register(trigger, queryOptions, onQueryCallback, cb)
888
+ register(trigger, queryOptions, onQueryCallback, _internalCb);
803
889
  } else {
804
- register(trigger, queryParams, onQueryCallback, cb)
890
+ register(trigger, queryParams, onQueryCallback, _internalCb);
805
891
  }
806
- }
807
- };
808
-
892
+ }, 0);
809
893
 
810
- if ( sdkVersion > 2 ) {
811
- if ( _mainCallback == null ) {
812
- setTimeout((trigger, queryOptions, onQueryCallback) => {
813
- if (!self._isRegisteredFromProto) {
814
- // needed when used as a synchrone method
815
- register(trigger, queryOptions, onQueryCallback);
816
- }
817
- }, 0, trigger, queryOptions, onQueryCallback);
818
- return _proto
894
+ return _promise;
819
895
 
820
- } else {
821
- register(trigger, queryOptions, onQueryCallback, _mainCallback)
822
- }
823
896
  } else {
824
-
825
- if ( _mainCallback == null ) {
826
- setTimeout((trigger, queryParams, onQueryCallback) => {
827
- if (!self._isRegisteredFromProto) {
828
- // needed when used as a synchrone method
829
- register(trigger, queryParams, onQueryCallback);
830
- }
831
- }, 0, trigger, queryParams, onQueryCallback);
832
- return _proto
833
-
897
+ // Direct callback path (util.promisify or explicit _mainCallback)
898
+ // unchanged, register() called synchronously.
899
+ if ( sdkVersion > 2 ) {
900
+ register(trigger, queryOptions, onQueryCallback, _mainCallback)
834
901
  } else {
835
902
  register(trigger, queryParams, onQueryCallback, _mainCallback)
836
903
  }
@@ -2169,8 +2169,8 @@ if ( /^local$/i.test(process.env.NODE_SCOPE) ) {
2169
2169
  },
2170
2170
  // Will try x3 (0, 1, 2). Hard ceiling is 10 (see retry handler) to bound timer accumulation under sustained failure.
2171
2171
  maxRetry : 2,
2172
- // Socket inactivity timeout in milliseconds
2173
- timeout : 10000,
2172
+ // Socket inactivity timeout accepts "30s", "500ms", "1m" or a number (ms)
2173
+ requestTimeout : "10s",
2174
2174
  agent : false/**,
2175
2175
  checkServerIdentity: function(host, cert) {
2176
2176
  // Make sure the certificate is issued to the host we are connected to
@@ -2256,6 +2256,21 @@ if ( /^local$/i.test(process.env.NODE_SCOPE) ) {
2256
2256
  , browser = null
2257
2257
  ;
2258
2258
 
2259
+ // Priority chain — all checks must run BEFORE merge(defaultOptions), which fills in "10s":
2260
+ // 1. options.requestTimeout — explicit call-site override (highest priority)
2261
+ // 2. req.routing.queryTimeout — per-route default from routing.json
2262
+ // 3. "10s" from defaultOptions (lowest, filled by merge below)
2263
+
2264
+ // Fall back to the calling route's queryTimeout if still not set.
2265
+ if (
2266
+ typeof options.requestTimeout === 'undefined'
2267
+ && typeof local.req !== 'undefined' && local.req
2268
+ && local.req.routing
2269
+ && local.req.routing.queryTimeout
2270
+ ) {
2271
+ options.requestTimeout = local.req.routing.queryTimeout;
2272
+ }
2273
+
2259
2274
  // options must be used as a copy in case of multiple calls of self.query(options, ...)
2260
2275
  options = merge(JSON.clone(options), defaultOptions);
2261
2276
  // replaced: for...in + delete — build filtered copy (#P22, #P20)
@@ -2268,6 +2283,10 @@ if ( /^local$/i.test(process.env.NODE_SCOPE) ) {
2268
2283
  }
2269
2284
  options = cleanedOptions;
2270
2285
 
2286
+ // Normalize requestTimeout to ms once — covers both HTTP/1 and HTTP/2 paths.
2287
+ if (typeof options.requestTimeout !== 'undefined') {
2288
+ options.requestTimeout = parseTimeout(options.requestTimeout);
2289
+ }
2271
2290
 
2272
2291
  if (self.isCacheless() || self.isLocalScope() ) {
2273
2292
  options.rejectUnauthorized = false;
@@ -2778,7 +2797,7 @@ if ( /^local$/i.test(process.env.NODE_SCOPE) ) {
2778
2797
  })
2779
2798
  });
2780
2799
 
2781
- req.setTimeout(options.timeout, () => {
2800
+ req.setTimeout(parseTimeout(options.requestTimeout), () => {
2782
2801
  req.destroy(); // Will trigger 'error' event
2783
2802
  });
2784
2803
 
@@ -2905,7 +2924,9 @@ if ( /^local$/i.test(process.env.NODE_SCOPE) ) {
2905
2924
 
2906
2925
  let client = cache.get(sessKey);
2907
2926
  // Checking client status: is closed or being closed
2908
- if (client && (client.closed || client.destroyed || client.connecting === false)) {
2927
+ // Note: client.connecting === false means the session is ESTABLISHED (connected), not stale.
2928
+ // Only evict sessions that are actually closed or destroyed.
2929
+ if (client && (client.closed || client.destroyed)) {
2909
2930
  client = null;
2910
2931
  cache.delete(sessKey);
2911
2932
  var _staleIdx = self.serverInstance._http2Sessions.indexOf(sessKey);
@@ -2970,9 +2991,8 @@ if ( /^local$/i.test(process.env.NODE_SCOPE) ) {
2970
2991
  _closeIdx = null;
2971
2992
  });
2972
2993
 
2973
- client.on('goaway', () => {
2994
+ client.on('goaway', (errorCode, lastStreamID) => {
2974
2995
  if (_pingInterval) { clearInterval(_pingInterval); _pingInterval = null; }
2975
- console.warn('[CLIENT] Server is going away. Draining session.');
2976
2996
  cache.delete(sessKey);
2977
2997
  var _goawayIdx = self.serverInstance._http2Sessions.indexOf(sessKey);
2978
2998
  if (_goawayIdx !== -1) self.serverInstance._http2Sessions.splice(_goawayIdx, 1);
@@ -3083,7 +3103,20 @@ if ( /^local$/i.test(process.env.NODE_SCOPE) ) {
3083
3103
  }
3084
3104
  // 2. CRUCIAL SECURITY: Remove manual content-length for HTTP/2
3085
3105
  // Node.js will calculate it automatically and correctly with req.end(body)
3086
- // Strict sanitization for HTTP/2 (no undefined/null values)
3106
+ // Strict sanitization for HTTP/2:
3107
+ // - Remove content-length (auto-computed by Node.js)
3108
+ // - Remove Buffer-valued entries (e.g. _body — the request body stash): sending a
3109
+ // 166KB Buffer as a header value exceeds maxHeaderListSize (64KB) and causes
3110
+ // nghttp2 to refuse the stream client-side with NGHTTP2_REFUSED_STREAM
3111
+ // - Remove known TLS/connection config keys that leaked in from the options object
3112
+ // and are not valid HTTP headers
3113
+ // - Remove undefined/null values
3114
+ var _NON_HTTP_OPTS = new Set([
3115
+ '_body', '_comment', 'ca', 'hostname', 'host', 'port',
3116
+ 'requestTimeout', 'keepAlive', 'maxSockets', 'keepAliveMsecs', 'maxFreeSockets',
3117
+ 'rejectUnauthorized', 'maxRetry', 'agent', 'protocol', 'scheme',
3118
+ 'nameservers', 'settings', 'webroot', 'queryData', 'method', 'path'
3119
+ ]);
3087
3120
  var headerKeys = Object.keys(headers);
3088
3121
  var cleanHeaders = {};
3089
3122
  for (var hi = 0; hi < headerKeys.length; ++hi) {
@@ -3091,6 +3124,8 @@ if ( /^local$/i.test(process.env.NODE_SCOPE) ) {
3091
3124
  if (
3092
3125
  hk !== 'content-length' && hk !== 'Content-Length'
3093
3126
  && headers[hk] !== undefined && headers[hk] !== null
3127
+ && !Buffer.isBuffer(headers[hk])
3128
+ && !_NON_HTTP_OPTS.has(hk)
3094
3129
  ) {
3095
3130
  cleanHeaders[hk] = headers[hk];
3096
3131
  }
@@ -3109,7 +3144,7 @@ if ( /^local$/i.test(process.env.NODE_SCOPE) ) {
3109
3144
  // silently drops idle inter-container TCP connections without RST or FIN).
3110
3145
  // On timeout: evict the dead session and retry once with a fresh connection.
3111
3146
  // If the retry also times out, surface the error to the caller.
3112
- var _streamTimeout = options.timeout || 10000;
3147
+ var _streamTimeout = parseTimeout(options.requestTimeout) || 10000;
3113
3148
  req.setTimeout(_streamTimeout, function onStreamTimeout() {
3114
3149
  if (isFinished) return;
3115
3150
  isFinished = true;
@@ -4294,7 +4329,17 @@ if ( /^local$/i.test(process.env.NODE_SCOPE) ) {
4294
4329
  arguments[arguments.length-1] instanceof Error
4295
4330
  || typeof(res) == 'object' && typeof(res.stack) != 'undefined'
4296
4331
  ) {
4297
- errorObject = merge(arguments[arguments.length-1], errorObject)
4332
+ var _lastArg = arguments[arguments.length-1];
4333
+ if (_lastArg instanceof Error) {
4334
+ // Error properties (message, stack) are non-enumerable —
4335
+ // merge() silently drops them. Extract explicitly so they
4336
+ // survive JSON.stringify and reach the client error dialog.
4337
+ if (_lastArg.message) errorObject.message = _lastArg.message;
4338
+ if (_lastArg.stack) errorObject.stack = _lastArg.stack;
4339
+ if (!errorObject.error) errorObject.error = _lastArg.message || standardErrorMessage;
4340
+ } else {
4341
+ errorObject = merge(_lastArg, errorObject);
4342
+ }
4298
4343
  } else if (
4299
4344
  !(arguments[arguments.length-1] instanceof Error)
4300
4345
  && typeof(res) == 'object'