gina 0.3.11 → 0.3.12

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 (400) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +8 -1
  3. package/framework/v0.3.12/VERSION +1 -0
  4. package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/js/gina.js +12 -1
  5. package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/js/gina.min.js +187 -186
  6. package/framework/v0.3.12/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
  7. package/framework/v0.3.12/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
  8. package/framework/{v0.3.11 → v0.3.12}/core/controller/controller.render-json.js +12 -3
  9. package/framework/{v0.3.11 → v0.3.12}/core/controller/controller.render-nunjucks.js +68 -54
  10. package/framework/{v0.3.11 → v0.3.12}/core/controller/controller.render-swig.js +173 -132
  11. package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/validator/src/form-validator.js +12 -1
  12. package/framework/{v0.3.11 → v0.3.12}/core/server.isaac.js +10 -2
  13. package/framework/{v0.3.11 → v0.3.12}/core/server.js +3 -3
  14. package/framework/{v0.3.11 → v0.3.12}/package.json +2 -2
  15. package/gna.js +4 -4
  16. package/llms.txt +3 -1
  17. package/package.json +2 -2
  18. package/framework/v0.3.11/VERSION +0 -1
  19. package/framework/v0.3.11/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
  20. package/framework/v0.3.11/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
  21. /package/framework/{v0.3.11 → v0.3.12}/AUTHORS +0 -0
  22. /package/framework/{v0.3.11 → v0.3.12}/LICENSE +0 -0
  23. /package/framework/{v0.3.11 → v0.3.12}/core/asset/html/nolayout.html +0 -0
  24. /package/framework/{v0.3.11 → v0.3.12}/core/asset/html/static.html +0 -0
  25. /package/framework/{v0.3.11 → v0.3.12}/core/asset/img/android-chrome-192x192.png +0 -0
  26. /package/framework/{v0.3.11 → v0.3.12}/core/asset/img/android-chrome-512x512.png +0 -0
  27. /package/framework/{v0.3.11 → v0.3.12}/core/asset/img/apple-touch-icon.png +0 -0
  28. /package/framework/{v0.3.11 → v0.3.12}/core/asset/img/favicon-16x16.png +0 -0
  29. /package/framework/{v0.3.11 → v0.3.12}/core/asset/img/favicon-32x32.png +0 -0
  30. /package/framework/{v0.3.11 → v0.3.12}/core/asset/img/favicon.ico +0 -0
  31. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/README.md +0 -0
  32. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.css +0 -0
  33. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.js +0 -0
  34. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/beemaster/index.html +0 -0
  35. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/css/gina.min.css +0 -0
  36. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.br +0 -0
  37. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.gz +0 -0
  38. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/html/statusbar.html +0 -0
  39. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.br +0 -0
  40. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.gz +0 -0
  41. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/inspector/have_heart_one-webfont.woff2 +0 -0
  42. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/inspector/index.html +0 -0
  43. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/inspector/inspector.css +0 -0
  44. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/inspector/inspector.js +0 -0
  45. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/inspector/logo.svg +0 -0
  46. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js +0 -0
  47. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.br +0 -0
  48. /package/framework/{v0.3.11 → v0.3.12}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.gz +0 -0
  49. /package/framework/{v0.3.11 → v0.3.12}/core/config.js +0 -0
  50. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/ai/index.js +0 -0
  51. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/ai/lib/connector.js +0 -0
  52. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/couchbase/index.js +0 -0
  53. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/couchbase/lib/connector.js +0 -0
  54. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/couchbase/lib/connector.v2.js +0 -0
  55. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/couchbase/lib/connector.v3.js +0 -0
  56. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/couchbase/lib/connector.v4.js +0 -0
  57. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/couchbase/lib/n1ql.js +0 -0
  58. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/couchbase/lib/session-store.js +0 -0
  59. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/couchbase/lib/session-store.v2.js +0 -0
  60. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/couchbase/lib/session-store.v3.js +0 -0
  61. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/couchbase/lib/session-store.v4.js +0 -0
  62. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/mongodb/index.js +0 -0
  63. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/mongodb/lib/connector.js +0 -0
  64. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/mongodb/lib/pipeline-loader.js +0 -0
  65. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/mongodb/lib/session-store.js +0 -0
  66. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/mysql/index.js +0 -0
  67. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/mysql/lib/connector.js +0 -0
  68. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/postgresql/index.js +0 -0
  69. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/postgresql/lib/connector.js +0 -0
  70. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/redis/index.js +0 -0
  71. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/redis/lib/session-store.js +0 -0
  72. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/scylladb/index.js +0 -0
  73. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/scylladb/lib/connector.js +0 -0
  74. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/scylladb/lib/session-store.js +0 -0
  75. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/sql-parser.js +0 -0
  76. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/sqlite/index.js +0 -0
  77. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/sqlite/lib/connector.js +0 -0
  78. /package/framework/{v0.3.11 → v0.3.12}/core/connectors/sqlite/lib/session-store.js +0 -0
  79. /package/framework/{v0.3.11 → v0.3.12}/core/content.encoding +0 -0
  80. /package/framework/{v0.3.11 → v0.3.12}/core/controller/controller.framework.js +0 -0
  81. /package/framework/{v0.3.11 → v0.3.12}/core/controller/controller.js +0 -0
  82. /package/framework/{v0.3.11 → v0.3.12}/core/controller/controller.render-stream.js +0 -0
  83. /package/framework/{v0.3.11 → v0.3.12}/core/controller/controller.render-v1.js +0 -0
  84. /package/framework/{v0.3.11 → v0.3.12}/core/controller/index.js +0 -0
  85. /package/framework/{v0.3.11 → v0.3.12}/core/deps/busboy-1.6.0/LICENSE +0 -0
  86. /package/framework/{v0.3.11 → v0.3.12}/core/deps/busboy-1.6.0/README.md +0 -0
  87. /package/framework/{v0.3.11 → v0.3.12}/core/deps/busboy-1.6.0/lib/index.js +0 -0
  88. /package/framework/{v0.3.11 → v0.3.12}/core/deps/busboy-1.6.0/lib/types/multipart.js +0 -0
  89. /package/framework/{v0.3.11 → v0.3.12}/core/deps/busboy-1.6.0/lib/types/urlencoded.js +0 -0
  90. /package/framework/{v0.3.11 → v0.3.12}/core/deps/busboy-1.6.0/lib/utils.js +0 -0
  91. /package/framework/{v0.3.11 → v0.3.12}/core/deps/busboy-1.6.0/package.json +0 -0
  92. /package/framework/{v0.3.11 → v0.3.12}/core/deps/streamsearch-1.1.0/LICENSE +0 -0
  93. /package/framework/{v0.3.11 → v0.3.12}/core/deps/streamsearch-1.1.0/lib/sbmh.js +0 -0
  94. /package/framework/{v0.3.11 → v0.3.12}/core/deps/streamsearch-1.1.0/package.json +0 -0
  95. /package/framework/{v0.3.11 → v0.3.12}/core/dev/index.js +0 -0
  96. /package/framework/{v0.3.11 → v0.3.12}/core/dev/lib/class.js +0 -0
  97. /package/framework/{v0.3.11 → v0.3.12}/core/dev/lib/factory.js +0 -0
  98. /package/framework/{v0.3.11 → v0.3.12}/core/dev/lib/tools.js +0 -0
  99. /package/framework/{v0.3.11 → v0.3.12}/core/gna.js +0 -0
  100. /package/framework/{v0.3.11 → v0.3.12}/core/locales/README.md +0 -0
  101. /package/framework/{v0.3.11 → v0.3.12}/core/locales/currency.json +0 -0
  102. /package/framework/{v0.3.11 → v0.3.12}/core/locales/dist/language/en.json +0 -0
  103. /package/framework/{v0.3.11 → v0.3.12}/core/locales/dist/language/fr.json +0 -0
  104. /package/framework/{v0.3.11 → v0.3.12}/core/locales/dist/region/en.json +0 -0
  105. /package/framework/{v0.3.11 → v0.3.12}/core/locales/dist/region/fr.json +0 -0
  106. /package/framework/{v0.3.11 → v0.3.12}/core/locales/index.js +0 -0
  107. /package/framework/{v0.3.11 → v0.3.12}/core/mime.types +0 -0
  108. /package/framework/{v0.3.11 → v0.3.12}/core/model/entity.js +0 -0
  109. /package/framework/{v0.3.11 → v0.3.12}/core/model/index.js +0 -0
  110. /package/framework/{v0.3.11 → v0.3.12}/core/model/template/entityFactory.js +0 -0
  111. /package/framework/{v0.3.11 → v0.3.12}/core/model/template/index.js +0 -0
  112. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/README.md +0 -0
  113. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/index.js +0 -0
  114. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/csrf/README.md +0 -0
  115. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/csrf/package.json +0 -0
  116. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/csrf/src/main.js +0 -0
  117. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/file/README.md +0 -0
  118. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/file/build.json +0 -0
  119. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/file/package.json +0 -0
  120. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/intl/README.md +0 -0
  121. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/intl/build.json +0 -0
  122. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/intl/package.json +0 -0
  123. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/intl/src/main.js +0 -0
  124. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/session/README.md +0 -0
  125. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/session/package.json +0 -0
  126. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/session/src/main.js +0 -0
  127. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/storage/README.md +0 -0
  128. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/storage/build.json +0 -0
  129. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/storage/package.json +0 -0
  130. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/storage/src/main.js +0 -0
  131. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/validator/README.md +0 -0
  132. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/validator/build.json +0 -0
  133. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/validator/package.json +0 -0
  134. /package/framework/{v0.3.11 → v0.3.12}/core/plugins/lib/validator/src/main.js +0 -0
  135. /package/framework/{v0.3.11 → v0.3.12}/core/router.js +0 -0
  136. /package/framework/{v0.3.11 → v0.3.12}/core/server.express.js +0 -0
  137. /package/framework/{v0.3.11 → v0.3.12}/core/status.codes +0 -0
  138. /package/framework/{v0.3.11 → v0.3.12}/core/template/_gitignore +0 -0
  139. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle/config/app.json +0 -0
  140. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle/config/connectors.json +0 -0
  141. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle/config/routing.json +0 -0
  142. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle/config/settings.json +0 -0
  143. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle/config/settings.server.json +0 -0
  144. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle/config/templates.json +0 -0
  145. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle/config/watchers.json +0 -0
  146. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle/controllers/controller.content.js +0 -0
  147. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle/controllers/controller.js +0 -0
  148. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle/controllers/setup.js +0 -0
  149. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle/index.js +0 -0
  150. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle/locales/en.json +0 -0
  151. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle_namespace/controllers/controller.js +0 -0
  152. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle_public/css/default.css +0 -0
  153. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle_public/css/home.css +0 -0
  154. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle_public/css/vendor/readme.md +0 -0
  155. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle_public/favicon.ico +0 -0
  156. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle_public/js/vendor/readme.md +0 -0
  157. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle_public/readme.md +0 -0
  158. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle_templates/handlers/main.js +0 -0
  159. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle_templates/html/content/homepage.html +0 -0
  160. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle_templates/html/includes/error-msg-noscript.html +0 -0
  161. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle_templates/html/includes/error-msg-outdated-browser.html +0 -0
  162. /package/framework/{v0.3.11 → v0.3.12}/core/template/boilerplate/bundle_templates/html/layouts/main.html +0 -0
  163. /package/framework/{v0.3.11 → v0.3.12}/core/template/command/gina.bat.tpl +0 -0
  164. /package/framework/{v0.3.11 → v0.3.12}/core/template/command/gina.tpl +0 -0
  165. /package/framework/{v0.3.11 → v0.3.12}/core/template/conf/env.json +0 -0
  166. /package/framework/{v0.3.11 → v0.3.12}/core/template/conf/manifest.json +0 -0
  167. /package/framework/{v0.3.11 → v0.3.12}/core/template/conf/package.json +0 -0
  168. /package/framework/{v0.3.11 → v0.3.12}/core/template/conf/settings.json +0 -0
  169. /package/framework/{v0.3.11 → v0.3.12}/core/template/conf/statics.json +0 -0
  170. /package/framework/{v0.3.11 → v0.3.12}/core/template/conf/templates.json +0 -0
  171. /package/framework/{v0.3.11 → v0.3.12}/core/template/error/client/json/401.json +0 -0
  172. /package/framework/{v0.3.11 → v0.3.12}/core/template/error/client/json/403.json +0 -0
  173. /package/framework/{v0.3.11 → v0.3.12}/core/template/error/client/json/404.json +0 -0
  174. /package/framework/{v0.3.11 → v0.3.12}/core/template/error/server/html/50x.html +0 -0
  175. /package/framework/{v0.3.11 → v0.3.12}/core/template/error/server/json/500.json +0 -0
  176. /package/framework/{v0.3.11 → v0.3.12}/core/template/error/server/json/503.json +0 -0
  177. /package/framework/{v0.3.11 → v0.3.12}/core/template/extensions/logger/config.json +0 -0
  178. /package/framework/{v0.3.11 → v0.3.12}/helpers/console.js +0 -0
  179. /package/framework/{v0.3.11 → v0.3.12}/helpers/context.js +0 -0
  180. /package/framework/{v0.3.11 → v0.3.12}/helpers/data/LICENSE +0 -0
  181. /package/framework/{v0.3.11 → v0.3.12}/helpers/data/README.md +0 -0
  182. /package/framework/{v0.3.11 → v0.3.12}/helpers/data/package.json +0 -0
  183. /package/framework/{v0.3.11 → v0.3.12}/helpers/data/src/main.js +0 -0
  184. /package/framework/{v0.3.11 → v0.3.12}/helpers/dateFormat.js +0 -0
  185. /package/framework/{v0.3.11 → v0.3.12}/helpers/index.js +0 -0
  186. /package/framework/{v0.3.11 → v0.3.12}/helpers/json/LICENSE +0 -0
  187. /package/framework/{v0.3.11 → v0.3.12}/helpers/json/README.md +0 -0
  188. /package/framework/{v0.3.11 → v0.3.12}/helpers/json/package.json +0 -0
  189. /package/framework/{v0.3.11 → v0.3.12}/helpers/json/src/main.js +0 -0
  190. /package/framework/{v0.3.11 → v0.3.12}/helpers/path.js +0 -0
  191. /package/framework/{v0.3.11 → v0.3.12}/helpers/plugins/README.md +0 -0
  192. /package/framework/{v0.3.11 → v0.3.12}/helpers/plugins/package.json +0 -0
  193. /package/framework/{v0.3.11 → v0.3.12}/helpers/plugins/src/api-error.js +0 -0
  194. /package/framework/{v0.3.11 → v0.3.12}/helpers/plugins/src/main.js +0 -0
  195. /package/framework/{v0.3.11 → v0.3.12}/helpers/prototypes.js +0 -0
  196. /package/framework/{v0.3.11 → v0.3.12}/helpers/task.js +0 -0
  197. /package/framework/{v0.3.11 → v0.3.12}/helpers/text.js +0 -0
  198. /package/framework/{v0.3.11 → v0.3.12}/lib/archiver/README.md +0 -0
  199. /package/framework/{v0.3.11 → v0.3.12}/lib/archiver/build.json +0 -0
  200. /package/framework/{v0.3.11 → v0.3.12}/lib/archiver/package.json +0 -0
  201. /package/framework/{v0.3.11 → v0.3.12}/lib/archiver/src/dep/jszip.min.js +0 -0
  202. /package/framework/{v0.3.11 → v0.3.12}/lib/archiver/src/main.js +0 -0
  203. /package/framework/{v0.3.11 → v0.3.12}/lib/async/package.json +0 -0
  204. /package/framework/{v0.3.11 → v0.3.12}/lib/async/src/main.js +0 -0
  205. /package/framework/{v0.3.11 → v0.3.12}/lib/cache/README.md +0 -0
  206. /package/framework/{v0.3.11 → v0.3.12}/lib/cache/build.json +0 -0
  207. /package/framework/{v0.3.11 → v0.3.12}/lib/cache/package.json +0 -0
  208. /package/framework/{v0.3.11 → v0.3.12}/lib/cache/src/main.js +0 -0
  209. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/aliases.json +0 -0
  210. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/add.js +0 -0
  211. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/arguments.json +0 -0
  212. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/build.js +0 -0
  213. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/copy.js +0 -0
  214. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/cp.js +0 -0
  215. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/help.js +0 -0
  216. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/help.txt +0 -0
  217. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/list.js +0 -0
  218. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/mcp-start.js +0 -0
  219. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/mcp.js +0 -0
  220. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/oas.js +0 -0
  221. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/openapi.js +0 -0
  222. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/remove.js +0 -0
  223. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/rename.js +0 -0
  224. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/restart.js +0 -0
  225. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/rm.js +0 -0
  226. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/start.js +0 -0
  227. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/status.js +0 -0
  228. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/bundle/stop.js +0 -0
  229. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/cache/stats.js +0 -0
  230. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/connector/add.js +0 -0
  231. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/connector/arguments.json +0 -0
  232. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/connector/help.js +0 -0
  233. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/connector/help.txt +0 -0
  234. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/connector/list.js +0 -0
  235. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/connector/migrate.js +0 -0
  236. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/connector/remove.js +0 -0
  237. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/connector/rm.js +0 -0
  238. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/env/add.js +0 -0
  239. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/env/get.js +0 -0
  240. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/env/help.js +0 -0
  241. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/env/help.txt +0 -0
  242. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/env/link-dev.js +0 -0
  243. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/env/list.js +0 -0
  244. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/env/remove.js +0 -0
  245. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/env/rm.js +0 -0
  246. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/env/set.js +0 -0
  247. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/env/unset.js +0 -0
  248. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/env/use.js +0 -0
  249. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/arguments.json +0 -0
  250. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/build.js +0 -0
  251. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/dot.js +0 -0
  252. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/get.js +0 -0
  253. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/help.js +0 -0
  254. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/help.txt +0 -0
  255. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/init.js +0 -0
  256. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/link-node-modules.js +0 -0
  257. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/link.js +0 -0
  258. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/msg.json +0 -0
  259. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/open.js +0 -0
  260. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/restart.js +0 -0
  261. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/set.js +0 -0
  262. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/start.js +0 -0
  263. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/status.js +0 -0
  264. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/stop.js +0 -0
  265. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/tail.js +0 -0
  266. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/update.js +0 -0
  267. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/framework/version.js +0 -0
  268. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/gina-dev.1.md +0 -0
  269. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/gina-framework.1.md +0 -0
  270. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/gina.1.md +0 -0
  271. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/helper.js +0 -0
  272. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/i18n/add.js +0 -0
  273. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/i18n/arguments.json +0 -0
  274. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/i18n/export.js +0 -0
  275. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/i18n/help.js +0 -0
  276. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/i18n/help.txt +0 -0
  277. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/i18n/import.js +0 -0
  278. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/i18n/scan.js +0 -0
  279. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/index.js +0 -0
  280. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/inspector/help.js +0 -0
  281. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/inspector/help.txt +0 -0
  282. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/inspector/open.js +0 -0
  283. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/minion/help.js +0 -0
  284. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/minion/help.txt +0 -0
  285. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/msg.json +0 -0
  286. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/port/help.js +0 -0
  287. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/port/help.txt +0 -0
  288. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/port/inc/scan.js +0 -0
  289. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/port/list.js +0 -0
  290. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/port/reset.js +0 -0
  291. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/port/set.js +0 -0
  292. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/project/add.js +0 -0
  293. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/project/arguments.json +0 -0
  294. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/project/build.js +0 -0
  295. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/project/help.js +0 -0
  296. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/project/help.txt +0 -0
  297. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/project/import.js +0 -0
  298. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/project/list.js +0 -0
  299. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/project/move.js +0 -0
  300. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/project/remove.js +0 -0
  301. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/project/rename.js +0 -0
  302. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/project/restart.js +0 -0
  303. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/project/rm.js +0 -0
  304. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/project/start.js +0 -0
  305. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/project/status.js +0 -0
  306. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/project/stop.js +0 -0
  307. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/protocol/help.js +0 -0
  308. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/protocol/help.txt +0 -0
  309. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/protocol/list.js +0 -0
  310. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/protocol/set.js +0 -0
  311. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/scope/add.js +0 -0
  312. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/scope/help.js +0 -0
  313. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/scope/help.txt +0 -0
  314. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/scope/link-local.js +0 -0
  315. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/scope/link-production.js +0 -0
  316. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/scope/list.js +0 -0
  317. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/scope/remove.js +0 -0
  318. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/scope/rm.js +0 -0
  319. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/scope/use.js +0 -0
  320. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/service/help.js +0 -0
  321. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/service/help.txt +0 -0
  322. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/service/list.js +0 -0
  323. /package/framework/{v0.3.11 → v0.3.12}/lib/cmd/view/add.js +0 -0
  324. /package/framework/{v0.3.11 → v0.3.12}/lib/collection/README.md +0 -0
  325. /package/framework/{v0.3.11 → v0.3.12}/lib/collection/build.json +0 -0
  326. /package/framework/{v0.3.11 → v0.3.12}/lib/collection/package.json +0 -0
  327. /package/framework/{v0.3.11 → v0.3.12}/lib/collection/src/main.js +0 -0
  328. /package/framework/{v0.3.11 → v0.3.12}/lib/config.js +0 -0
  329. /package/framework/{v0.3.11 → v0.3.12}/lib/connector-registry/package.json +0 -0
  330. /package/framework/{v0.3.11 → v0.3.12}/lib/connector-registry/src/main.js +0 -0
  331. /package/framework/{v0.3.11 → v0.3.12}/lib/cron/README.md +0 -0
  332. /package/framework/{v0.3.11 → v0.3.12}/lib/cron/package.json +0 -0
  333. /package/framework/{v0.3.11 → v0.3.12}/lib/cron/src/main.js +0 -0
  334. /package/framework/{v0.3.11 → v0.3.12}/lib/domain/LICENSE +0 -0
  335. /package/framework/{v0.3.11 → v0.3.12}/lib/domain/README.md +0 -0
  336. /package/framework/{v0.3.11 → v0.3.12}/lib/domain/package.json +0 -0
  337. /package/framework/{v0.3.11 → v0.3.12}/lib/domain/src/main.js +0 -0
  338. /package/framework/{v0.3.11 → v0.3.12}/lib/generator/index.js +0 -0
  339. /package/framework/{v0.3.11 → v0.3.12}/lib/i18n/package.json +0 -0
  340. /package/framework/{v0.3.11 → v0.3.12}/lib/i18n/src/main.js +0 -0
  341. /package/framework/{v0.3.11 → v0.3.12}/lib/index.js +0 -0
  342. /package/framework/{v0.3.11 → v0.3.12}/lib/inherits/LICENSE +0 -0
  343. /package/framework/{v0.3.11 → v0.3.12}/lib/inherits/README.md +0 -0
  344. /package/framework/{v0.3.11 → v0.3.12}/lib/inherits/package.json +0 -0
  345. /package/framework/{v0.3.11 → v0.3.12}/lib/inherits/src/main.js +0 -0
  346. /package/framework/{v0.3.11 → v0.3.12}/lib/inspector-redact/package.json +0 -0
  347. /package/framework/{v0.3.11 → v0.3.12}/lib/inspector-redact/src/main.js +0 -0
  348. /package/framework/{v0.3.11 → v0.3.12}/lib/logger/README.md +0 -0
  349. /package/framework/{v0.3.11 → v0.3.12}/lib/logger/package.json +0 -0
  350. /package/framework/{v0.3.11 → v0.3.12}/lib/logger/src/containers/default/index.js +0 -0
  351. /package/framework/{v0.3.11 → v0.3.12}/lib/logger/src/containers/file/index.js +0 -0
  352. /package/framework/{v0.3.11 → v0.3.12}/lib/logger/src/containers/file/lib/logrotator/README.md +0 -0
  353. /package/framework/{v0.3.11 → v0.3.12}/lib/logger/src/containers/file/lib/logrotator/index.js +0 -0
  354. /package/framework/{v0.3.11 → v0.3.12}/lib/logger/src/containers/mq/index.js +0 -0
  355. /package/framework/{v0.3.11 → v0.3.12}/lib/logger/src/containers/mq/listener.js +0 -0
  356. /package/framework/{v0.3.11 → v0.3.12}/lib/logger/src/containers/mq/speaker.js +0 -0
  357. /package/framework/{v0.3.11 → v0.3.12}/lib/logger/src/helper.js +0 -0
  358. /package/framework/{v0.3.11 → v0.3.12}/lib/logger/src/main.js +0 -0
  359. /package/framework/{v0.3.11 → v0.3.12}/lib/math/index.js +0 -0
  360. /package/framework/{v0.3.11 → v0.3.12}/lib/mcp-dispatch/package.json +0 -0
  361. /package/framework/{v0.3.11 → v0.3.12}/lib/mcp-dispatch/src/main.js +0 -0
  362. /package/framework/{v0.3.11 → v0.3.12}/lib/mcp-http/package.json +0 -0
  363. /package/framework/{v0.3.11 → v0.3.12}/lib/mcp-http/src/main.js +0 -0
  364. /package/framework/{v0.3.11 → v0.3.12}/lib/mcp-server/package.json +0 -0
  365. /package/framework/{v0.3.11 → v0.3.12}/lib/mcp-server/src/main.js +0 -0
  366. /package/framework/{v0.3.11 → v0.3.12}/lib/merge/README.md +0 -0
  367. /package/framework/{v0.3.11 → v0.3.12}/lib/merge/package.json +0 -0
  368. /package/framework/{v0.3.11 → v0.3.12}/lib/merge/src/main.js +0 -0
  369. /package/framework/{v0.3.11 → v0.3.12}/lib/metrics/package.json +0 -0
  370. /package/framework/{v0.3.11 → v0.3.12}/lib/metrics/src/main.js +0 -0
  371. /package/framework/{v0.3.11 → v0.3.12}/lib/model.js +0 -0
  372. /package/framework/{v0.3.11 → v0.3.12}/lib/nunjucks-filters/README.md +0 -0
  373. /package/framework/{v0.3.11 → v0.3.12}/lib/nunjucks-filters/package.json +0 -0
  374. /package/framework/{v0.3.11 → v0.3.12}/lib/nunjucks-filters/src/main.js +0 -0
  375. /package/framework/{v0.3.11 → v0.3.12}/lib/nunjucks-resolver/package.json +0 -0
  376. /package/framework/{v0.3.11 → v0.3.12}/lib/nunjucks-resolver/src/main.js +0 -0
  377. /package/framework/{v0.3.11 → v0.3.12}/lib/proc.js +0 -0
  378. /package/framework/{v0.3.11 → v0.3.12}/lib/routing/README.md +0 -0
  379. /package/framework/{v0.3.11 → v0.3.12}/lib/routing/build.json +0 -0
  380. /package/framework/{v0.3.11 → v0.3.12}/lib/routing/package.json +0 -0
  381. /package/framework/{v0.3.11 → v0.3.12}/lib/routing/src/main.js +0 -0
  382. /package/framework/{v0.3.11 → v0.3.12}/lib/routing/src/radix.js +0 -0
  383. /package/framework/{v0.3.11 → v0.3.12}/lib/routing-introspect/package.json +0 -0
  384. /package/framework/{v0.3.11 → v0.3.12}/lib/routing-introspect/src/main.js +0 -0
  385. /package/framework/{v0.3.11 → v0.3.12}/lib/session-store.js +0 -0
  386. /package/framework/{v0.3.11 → v0.3.12}/lib/shell.js +0 -0
  387. /package/framework/{v0.3.11 → v0.3.12}/lib/state.js +0 -0
  388. /package/framework/{v0.3.11 → v0.3.12}/lib/swig-filters/README.md +0 -0
  389. /package/framework/{v0.3.11 → v0.3.12}/lib/swig-filters/package.json +0 -0
  390. /package/framework/{v0.3.11 → v0.3.12}/lib/swig-filters/src/main.js +0 -0
  391. /package/framework/{v0.3.11 → v0.3.12}/lib/swig-resolver/package.json +0 -0
  392. /package/framework/{v0.3.11 → v0.3.12}/lib/swig-resolver/src/main.js +0 -0
  393. /package/framework/{v0.3.11 → v0.3.12}/lib/url/README.md +0 -0
  394. /package/framework/{v0.3.11 → v0.3.12}/lib/url/index.js +0 -0
  395. /package/framework/{v0.3.11 → v0.3.12}/lib/url/routing.json +0 -0
  396. /package/framework/{v0.3.11 → v0.3.12}/lib/uuid/package.json +0 -0
  397. /package/framework/{v0.3.11 → v0.3.12}/lib/uuid/src/main.js +0 -0
  398. /package/framework/{v0.3.11 → v0.3.12}/lib/validator.js +0 -0
  399. /package/framework/{v0.3.11 → v0.3.12}/lib/watcher/package.json +0 -0
  400. /package/framework/{v0.3.11 → v0.3.12}/lib/watcher/src/main.js +0 -0
@@ -30,25 +30,27 @@ var self = null
30
30
  * @param {string} bundle - Bundle name (used as cache-key namespace)
31
31
  * @param {object} opt - Server cache configuration (`opt.path`, `opt.ttl`)
32
32
  * @param {string} htmlContent - Compiled HTML string to cache
33
+ * @param {object} req - Per-request request captured by render() (function-scoped, race-safe)
34
+ * @param {object} res - Per-request response captured by render() (function-scoped, race-safe)
33
35
  * @returns {Promise<void>}
34
36
  */
35
- async function writeCache(bundle, opt, htmlContent) {
37
+ async function writeCache(bundle, opt, htmlContent, req, res) {
36
38
  if (
37
- typeof(local.req.routing.cache) == 'undefined'
39
+ typeof(req.routing.cache) == 'undefined'
38
40
  ||
39
- ! local.req.routing.cache
41
+ ! req.routing.cache
40
42
  ||
41
43
  // replaced: /^true$/i.test() (#P6)
42
44
  String(self.serverInstance._cacheIsEnabled).toLowerCase() !== 'true'
43
45
  ) {
44
46
  return;
45
47
  }
46
- // before: "static:" + local.req.originalUrl (#C3 — added bundle namespace to prevent silent collisions when two bundles serve the same URL path)
47
- var cacheKey = "static:" + bundle + ":" + local.req.originalUrl;
48
- var responseHeaders = local.res.getHeaders() || {};
48
+ // before: "static:" + req.originalUrl (#C3 — added bundle namespace to prevent silent collisions when two bundles serve the same URL path)
49
+ var cacheKey = "static:" + bundle + ":" + req.originalUrl;
50
+ var responseHeaders = res.getHeaders() || {};
49
51
  if ( !cache.has(cacheKey) ) {
50
52
  // Caching kinds are: `memory` & `fs`
51
- var cachingOption = ( typeof(local.req.routing.cache) == 'string' ) ? { type: local.req.routing.cache } : JSON.clone(local.req.routing.cache);
53
+ var cachingOption = ( typeof(req.routing.cache) == 'string' ) ? { type: req.routing.cache } : JSON.clone(req.routing.cache);
52
54
  if ( typeof(cachingOption.ttl) == 'undefined' ) {
53
55
  cachingOption.ttl = opt.ttl
54
56
  }
@@ -90,7 +92,7 @@ async function writeCache(bundle, opt, htmlContent) {
90
92
  // - prioritize content linked to sessions
91
93
  // - default ttl is 3600 sec
92
94
  if ( /^fs$/i.test(cachingOption.type) ) {
93
- var url = local.req.originalUrl;
95
+ var url = req.originalUrl;
94
96
  // replaced: /\/$/.test(url) (#P7)
95
97
  if ( url.endsWith('/') ) {
96
98
  url += 'index'
@@ -119,7 +121,7 @@ async function writeCache(bundle, opt, htmlContent) {
119
121
  // Invalidation
120
122
  if ( typeof(cachingOption.invalidateOnEvents) != 'undefined' ) {
121
123
  if ( !Array.isArray(cachingOption.invalidateOnEvents) ) {
122
- return self.throwError(local.res, 500, new Error('cache.invalidateOn must be an array'));
124
+ return self.throwError(res, 500, new Error('cache.invalidateOn must be an array'));
123
125
  }
124
126
  // Placing event listeners
125
127
  cache.setEvents(cacheKey, cachingOption.invalidateOnEvents);
@@ -167,6 +169,21 @@ module.exports = async function render(userData, displayInspector, errOptions, d
167
169
  SwigFilters = deps.SwigFilters;
168
170
  headersSent = deps.headersSent;
169
171
  ;
172
+ // Function-scoped captures of per-request refs. The exported render()
173
+ // is async with multiple await boundaries (template + layout reads,
174
+ // cache writes). Between yields, `local.req` / `local.res` / `local.next`
175
+ // can be nulled by another path on the same controller — most commonly
176
+ // throwError's generic-error fallthrough that runs when a second
177
+ // throwError fires after renderCustomError already started this render
178
+ // (see controller.js: the fallthrough ends the response and nulls the
179
+ // closure refs while we are suspended at await). Capturing into
180
+ // function-scoped locals isolates this render from that null-out so
181
+ // post-await reads do not dereference null. Terminal exits still null
182
+ // `local.req` / `local.res` / `local.next` on the closure to release
183
+ // per-request memory.
184
+ var req = local.req;
185
+ var res = local.res;
186
+ var _next = local.next;
170
187
  // Using server cache to cache compiledTemplates
171
188
  cache.from(self.serverInstance._cached);
172
189
 
@@ -214,36 +231,36 @@ module.exports = async function render(userData, displayInspector, errOptions, d
214
231
  , stream = null
215
232
  ;
216
233
 
217
- if ( typeof(local.res.stream) != 'undefined') {
218
- stream = local.res.stream
234
+ if ( typeof(res.stream) != 'undefined') {
235
+ stream = res.stream
219
236
  }
220
237
 
221
238
  try {
222
239
  data = getData();
223
240
  // Display session
224
241
  if (
225
- typeof(local.req.session) != 'undefined'
242
+ typeof(req.session) != 'undefined'
226
243
  ) {
227
244
  if ( typeof(data.page.data) == 'undefined' ) {
228
245
  data.page.data = {};
229
246
  }
230
247
 
231
- if ( typeof(local.req.session.cookie._expires) != 'undefined' ) {
232
- var dateEnd = local.req.session.cookie._expires;
233
- var dateStart = ( typeof(local.req.session.lastModified) != 'undefined')
234
- ? new Date(local.req.session.lastModified)
248
+ if ( typeof(req.session.cookie._expires) != 'undefined' ) {
249
+ var dateEnd = req.session.cookie._expires;
250
+ var dateStart = ( typeof(req.session.lastModified) != 'undefined')
251
+ ? new Date(req.session.lastModified)
235
252
  : new Date()
236
253
  ;
237
254
  var elapsed = dateEnd - dateStart;
238
255
  // var expiresAt =
239
256
  if ( typeof(data.page.data.session) == 'undefined' ) {
240
257
  data.page.data.session = {
241
- id : local.req.session.id,
242
- lastModified: local.req.session.lastModified
258
+ id : req.session.id,
259
+ lastModified: req.session.lastModified
243
260
  };
244
261
  }
245
262
  // In milliseconds
246
- data.page.data.session.createdAt = local.req.session.createdAt;
263
+ data.page.data.session.createdAt = req.session.createdAt;
247
264
  data.page.data.session.expiresAt = dateEnd.format('isoDateTime');
248
265
  data.page.data.session.timeout = elapsed;
249
266
 
@@ -253,18 +270,18 @@ module.exports = async function render(userData, displayInspector, errOptions, d
253
270
  }
254
271
  }
255
272
 
256
- // in case `local.req.routing.param.file` has been changed on the fly
273
+ // in case `req.routing.param.file` has been changed on the fly
257
274
  if (
258
- local.req.routing.param.file
259
- && local.req.routing.param.file != data.page.view.file
275
+ req.routing.param.file
276
+ && req.routing.param.file != data.page.view.file
260
277
  ) {
261
- data.page.view.file = local.req.routing.param.file;
278
+ data.page.view.file = req.routing.param.file;
262
279
  }
263
280
  if (
264
- local.req.routing.param.ext
265
- && local.req.routing.param.ext != data.page.view.ext
281
+ req.routing.param.ext
282
+ && req.routing.param.ext != data.page.view.ext
266
283
  ) {
267
- data.page.view.ext = local.req.routing.param.ext;
284
+ data.page.view.ext = req.routing.param.ext;
268
285
  }
269
286
  file = (isRenderingCustomError) ? localOptions.file : data.page.view.file;
270
287
  // making path thru [namespace &] file
@@ -383,15 +400,20 @@ module.exports = async function render(userData, displayInspector, errOptions, d
383
400
  var newLayoutPath = 'swig' + subFolder +'/'+ layoutPath;
384
401
  newLayoutFilename = _(cachePath +'/'+ localOptions.bundle +'/'+ newLayoutPath, true);
385
402
 
386
- // For dev/cacheless envs
387
- if (
403
+ // In dev/cacheless mode we always refresh the cached layout;
404
+ // in cached mode we only write when it is missing. Previously
405
+ // the dev branch did rmSync()+writeFile(), opening a gap window
406
+ // where a concurrent request could observe the file as absent
407
+ // between two parallel renders and ENOENT at the readFile call
408
+ // ~340 lines below. The atomic temp+rename pattern below closes
409
+ // that window: the target is always either the previous
410
+ // content or the new content, never absent.
411
+ var shouldWriteLayoutCache = (
388
412
  String(self.serverInstance._cacheIsEnabled).toLowerCase() !== 'true'
389
- && fs.existsSync( newLayoutFilename )
390
- ) {
391
- fs.rmSync( newLayoutFilename )
392
- }
413
+ || !fs.existsSync( newLayoutFilename )
414
+ );
393
415
 
394
- if ( !fs.existsSync( newLayoutFilename ) ) {
416
+ if ( shouldWriteLayoutCache ) {
395
417
  var newLayoutDir = newLayoutFilename.split(/\//g).slice(0, -1).join('/');
396
418
  var newLayoutDirObj = new _(newLayoutDir);
397
419
  if ( !newLayoutDirObj.existsSync() ) {
@@ -416,7 +438,14 @@ module.exports = async function render(userData, displayInspector, errOptions, d
416
438
  // replaced: openSync/readFileSync/writeSync/closeSync — async read + write (#P29, #P31)
417
439
  // buffer = Buffer.from( fs.readFileSync(localOptions.template.html + '/'+ layoutPath) ); // replaced: CVE-2023-25345
418
440
  buffer = await fs.promises.readFile(localOptions.template.html + '/'+ layoutPath);
419
- await fs.promises.writeFile(newLayoutFilename, buffer);
441
+ // Atomic write: temp file + rename. rename(2) on POSIX is
442
+ // atomic on the same filesystem, so concurrent readers at
443
+ // the post-priming readFile below never see the target
444
+ // absent.
445
+ var _layoutTmp = newLayoutFilename + '.tmp.' + process.pid + '.' + Date.now() + '.' + Math.random().toString(36).slice(2);
446
+ await fs.promises.writeFile(_layoutTmp, buffer);
447
+ await fs.promises.rename(_layoutTmp, newLayoutFilename);
448
+ _layoutTmp = null;
420
449
  buffer = null;
421
450
  }
422
451
 
@@ -452,15 +481,15 @@ module.exports = async function render(userData, displayInspector, errOptions, d
452
481
  // specific override
453
482
  if (
454
483
  self.isCacheless()
455
- && typeof(local.req[ local.req.method.toLowerCase() ]) != 'undefined'
456
- && typeof(local.req[ local.req.method.toLowerCase() ].debug) != 'undefined'
484
+ && typeof(req[ req.method.toLowerCase() ]) != 'undefined'
485
+ && typeof(req[ req.method.toLowerCase() ].debug) != 'undefined'
457
486
  ) {
458
487
  // replaced: /^(true|false)$/i.test() — use string comparison (#P6)
459
- var _debugVal = String(local.req[ local.req.method.toLowerCase() ].debug).toLowerCase();
488
+ var _debugVal = String(req[ req.method.toLowerCase() ].debug).toLowerCase();
460
489
  if ( _debugVal !== 'true' && _debugVal !== 'false' ) {
461
- console.warn('Detected wrong value for `debug`: '+ local.req[ local.req.method.toLowerCase() ].debug);
490
+ console.warn('Detected wrong value for `debug`: '+ req[ req.method.toLowerCase() ].debug);
462
491
  console.warn('Switching `debug` to `true` as `cacheless` mode is enabled');
463
- local.req[ local.req.method.toLowerCase() ].debug = true;
492
+ req[ req.method.toLowerCase() ].debug = true;
464
493
  _debugVal = 'true';
465
494
  }
466
495
  localOptions.debugMode = _debugVal === 'true';
@@ -500,16 +529,16 @@ module.exports = async function render(userData, displayInspector, errOptions, d
500
529
 
501
530
  // Allowing file & ext override
502
531
  if (
503
- typeof(local.req.routing.param.file) != 'undefined'
504
- && data.page.view.file !== local.req.routing.param.file
532
+ typeof(req.routing.param.file) != 'undefined'
533
+ && data.page.view.file !== req.routing.param.file
505
534
  ) {
506
- data.page.view.file = localOptions.file = local.req.routing.param.file
535
+ data.page.view.file = localOptions.file = req.routing.param.file
507
536
  }
508
537
  if (
509
- typeof(local.req.routing.param.ext) != 'undefined'
510
- && data.page.view.ext !== local.req.routing.param.ext
538
+ typeof(req.routing.param.ext) != 'undefined'
539
+ && data.page.view.ext !== req.routing.param.ext
511
540
  ) {
512
- data.page.view.ext = localOptions.template.ext = local.req.routing.param.ext
541
+ data.page.view.ext = localOptions.template.ext = req.routing.param.ext
513
542
  }
514
543
 
515
544
 
@@ -603,23 +632,23 @@ module.exports = async function render(userData, displayInspector, errOptions, d
603
632
  return;
604
633
  }
605
634
 
606
- var localRequestPort = local.req.headers.port || local.req.headers[':port'];
635
+ var localRequestPort = req.headers.port || req.headers[':port'];
607
636
  var isProxyHost = (
608
- typeof(local.req.headers.host) != 'undefined'
637
+ typeof(req.headers.host) != 'undefined'
609
638
  && typeof(localRequestPort) != 'undefined'
610
639
  && (localRequestPort === '80' || localRequestPort === '443' || localRequestPort === 80 || localRequestPort === 443)
611
- && localOptions.conf.server.scheme +'://'+ local.req.headers.host+':'+ localRequestPort != localOptions.conf.hostname.replace(/\:\d+$/, '') +':'+ localOptions.conf.server.port
640
+ && localOptions.conf.server.scheme +'://'+ req.headers.host+':'+ localRequestPort != localOptions.conf.hostname.replace(/\:\d+$/, '') +':'+ localOptions.conf.server.port
612
641
  ||
613
- typeof(local.req.headers[':authority']) != 'undefined'
614
- && localOptions.conf.server.scheme +'://'+ local.req.headers[':authority'] != localOptions.conf.hostname
642
+ typeof(req.headers[':authority']) != 'undefined'
643
+ && localOptions.conf.server.scheme +'://'+ req.headers[':authority'] != localOptions.conf.hostname
615
644
  ||
616
- typeof(local.req.headers.host) != 'undefined'
645
+ typeof(req.headers.host) != 'undefined'
617
646
  && typeof(localRequestPort) != 'undefined'
618
647
  && (localRequestPort === '80' || localRequestPort === '443' || localRequestPort === 80 || localRequestPort === 443)
619
- && local.req.headers.host == localOptions.conf.host
648
+ && req.headers.host == localOptions.conf.host
620
649
  ||
621
- typeof(local.req.headers['x-nginx-proxy']) != 'undefined'
622
- && String(local.req.headers['x-nginx-proxy']).toLowerCase() === 'true'
650
+ typeof(req.headers['x-nginx-proxy']) != 'undefined'
651
+ && String(req.headers['x-nginx-proxy']).toLowerCase() === 'true'
623
652
  ||
624
653
  typeof(process.gina.PROXY_HOSTNAME) != 'undefined'
625
654
  ) ? true : false;
@@ -630,8 +659,8 @@ module.exports = async function render(userData, displayInspector, errOptions, d
630
659
  options : JSON.clone(localOptions),
631
660
  isProxyHost : isProxyHost,
632
661
  throwError : self.throwError,
633
- req : local.req,
634
- res : local.res
662
+ req : req,
663
+ res : res
635
664
  });
636
665
  try {
637
666
 
@@ -647,7 +676,7 @@ module.exports = async function render(userData, displayInspector, errOptions, d
647
676
  }
648
677
  }
649
678
  } catch (err) {
650
- self.throwError(local.res, 500, new Error('[SwigFilters] template filters setup exception encoutered: [ '+path+' ]\n'+(err.stack||err.message)));
679
+ self.throwError(res, 500, new Error('[SwigFilters] template filters setup exception encoutered: [ '+path+' ]\n'+(err.stack||err.message)));
651
680
  return;
652
681
  }
653
682
 
@@ -711,7 +740,7 @@ module.exports = async function render(userData, displayInspector, errOptions, d
711
740
  if (!headersSent()) {
712
741
 
713
742
  //catching errors
714
- local.res.statusCode = ( typeof(localOptions.conf.server.coreConfiguration.statusCodes[data.page.data.status]) != 'undefined' ) ? data.page.data.status : 200; // by default
743
+ res.statusCode = ( typeof(localOptions.conf.server.coreConfiguration.statusCodes[data.page.data.status]) != 'undefined' ) ? data.page.data.status : 200; // by default
715
744
 
716
745
  // HTTP/2 (RFC7540 8.1.2.4):
717
746
  // This standard for HTTP/2 explicitly states that status messages are not supported.
@@ -730,14 +759,14 @@ module.exports = async function render(userData, displayInspector, errOptions, d
730
759
  ) {
731
760
 
732
761
  try {
733
- local.res.statusMessage = localOptions.conf.server.coreConfiguration.statusCodes[data.page.data.status];
762
+ res.statusMessage = localOptions.conf.server.coreConfiguration.statusCodes[data.page.data.status];
734
763
  } catch (err){
735
- local.res.statusCode = 500;
736
- local.res.statusMessage = err.stack||err.message||localOptions.conf.server.coreConfiguration.statusCodes[local.res.statusCode];
764
+ res.statusCode = 500;
765
+ res.statusMessage = err.stack||err.message||localOptions.conf.server.coreConfiguration.statusCodes[res.statusCode];
737
766
  }
738
767
  }
739
768
 
740
- local.res.setHeader('content-type', localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding );
769
+ res.setHeader('content-type', localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding );
741
770
 
742
771
  try {
743
772
 
@@ -749,7 +778,7 @@ module.exports = async function render(userData, displayInspector, errOptions, d
749
778
  filename = localOptions.template.html;
750
779
  // replaced: new RegExp('^' + namespace + '-') — use startsWith instead (#P2)
751
780
  filename += ( typeof(data.page.view.namespace) != 'undefined' && data.page.view.namespace != '' && data.page.view.file.startsWith(data.page.view.namespace + '-') ) ? '/' + 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: '' );
752
- self.throwError(local.res, 500, new Error('Controller::render(...) compilation error encountered while trying to process template `'+ filename + '`\n' + (err.stack||err.message||err) ));
781
+ self.throwError(res, 500, new Error('Controller::render(...) compilation error encountered while trying to process template `'+ filename + '`\n' + (err.stack||err.message||err) ));
753
782
  filename = null;
754
783
  return;
755
784
  }
@@ -816,27 +845,27 @@ module.exports = async function render(userData, displayInspector, errOptions, d
816
845
  detail: (data.page.view.file || null)
817
846
  });
818
847
  }
819
- local.res.setHeader('content-type', localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding );
848
+ res.setHeader('content-type', localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding );
820
849
 
821
850
  if (
822
851
  !self.isCacheless()
823
- && typeof(local.req.routing.cache) != 'undefined'
824
- && local.req.method.toUpperCase() === 'GET'
852
+ && typeof(req.routing.cache) != 'undefined'
853
+ && req.method.toUpperCase() === 'GET'
825
854
  ||
826
855
  // allowing caching even for dev env
827
856
  String(self.serverInstance._cacheIsEnabled).toLowerCase() === 'true'
828
- && typeof(local.req.routing.cache) != 'undefined'
829
- && local.req.method.toUpperCase() === 'GET'
857
+ && typeof(req.routing.cache) != 'undefined'
858
+ && req.method.toUpperCase() === 'GET'
830
859
  ) {
831
- await writeCache(localOptions.bundle, localOptions.conf.server.cache, htmlContent);
860
+ await writeCache(localOptions.bundle, localOptions.conf.server.cache, htmlContent, req, res);
832
861
  }
833
862
 
834
863
  // Cache-Control: miss path — inform browsers/CDNs of the response lifetime (#C6)
835
- if ( typeof(local.req.routing.cache) != 'undefined' && local.req.routing.cache ) {
836
- var _ccCfg = ( typeof(local.req.routing.cache) == 'string' ) ? { type: local.req.routing.cache } : local.req.routing.cache;
864
+ if ( typeof(req.routing.cache) != 'undefined' && req.routing.cache ) {
865
+ var _ccCfg = ( typeof(req.routing.cache) == 'string' ) ? { type: req.routing.cache } : req.routing.cache;
837
866
  var _ccTtl = ( typeof(_ccCfg.ttl) != 'undefined' && _ccCfg.ttl > 0 ) ? _ccCfg.ttl : localOptions.conf.server.cache.ttl;
838
867
  if ( _ccTtl > 0 ) {
839
- local.res.setHeader('Cache-Control', ( _ccCfg.visibility === 'public' ? 'public' : 'private' ) + ', max-age=' + ~~(_ccTtl));
868
+ res.setHeader('Cache-Control', ( _ccCfg.visibility === 'public' ? 'public' : 'private' ) + ', max-age=' + ~~(_ccTtl));
840
869
  }
841
870
  }
842
871
 
@@ -873,29 +902,29 @@ module.exports = async function render(userData, displayInspector, errOptions, d
873
902
  }
874
903
  }
875
904
 
876
- console.info(local.req.method +' ['+local.res.statusCode +'] '+ local.req.url);
905
+ console.info(req.method +' ['+res.statusCode +'] '+ req.url);
877
906
  // HEAD: send headers only — body suppressed (HTTP spec §4.3.2)
878
- if ( /^HEAD$/i.test(local.req.method) ) {
907
+ if ( /^HEAD$/i.test(req.method) ) {
879
908
  if ( stream ) {
880
909
  // #H8 — HTTP/2 HEAD: stream.respond() with content-length, no body.
881
910
  if ( !stream.headersSent ) {
882
911
  var _headH = {
883
912
  'content-type' : localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding,
884
913
  'content-length' : Buffer.byteLength(htmlContent, 'utf8'),
885
- ':status' : local.res.statusCode || 200
914
+ ':status' : res.statusCode || 200
886
915
  };
887
- var _pendingH = local.res.getHeaders ? local.res.getHeaders() : {};
916
+ var _pendingH = res.getHeaders ? res.getHeaders() : {};
888
917
  for (var _hk in _pendingH) {
889
918
  if (!(_hk in _headH)) _headH[_hk] = _pendingH[_hk];
890
919
  }
891
920
  stream.respond(_headH);
892
921
  }
893
922
  stream.end();
894
- local.res.headersSent = true;
923
+ res.headersSent = true;
895
924
  } else {
896
- local.res.setHeader('content-type', localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding);
897
- local.res.setHeader('content-length', Buffer.byteLength(htmlContent, 'utf8'));
898
- local.res.end();
925
+ res.setHeader('content-type', localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding);
926
+ res.setHeader('content-length', Buffer.byteLength(htmlContent, 'utf8'));
927
+ res.end();
899
928
  }
900
929
  } else if ( stream ) {
901
930
  // #H8 — Direct HTTP/2 stream: bypass HTTP/1.1 compat layer.
@@ -903,33 +932,35 @@ module.exports = async function render(userData, displayInspector, errOptions, d
903
932
  // before the async callback completed. stream.destroyed is true in that
904
933
  // case — respond() would throw ERR_HTTP2_INVALID_STREAM.
905
934
  if (stream.destroyed || stream.closed) {
906
- console.warn('[render-swig] Stream already destroyed — client disconnected before response was sent ('+ local.req.url +')');
935
+ console.warn('[render-swig] Stream already destroyed — client disconnected before response was sent ('+ req.url +')');
907
936
  } else {
908
937
  if ( !stream.headersSent ) {
909
938
  var _streamHeaders = {
910
939
  'content-type' : localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding,
911
- ':status' : local.res.statusCode || 200
940
+ ':status' : res.statusCode || 200
912
941
  };
913
942
  // Merge headers set earlier in the pipeline (CORS, cache-control, etc.)
914
943
  // — stream.respond() on the raw HTTP/2 stream does not include headers
915
944
  // set via response.setHeader().
916
- var _pendingHeaders = local.res.getHeaders ? local.res.getHeaders() : {};
945
+ var _pendingHeaders = res.getHeaders ? res.getHeaders() : {};
917
946
  for (var _rhk in _pendingHeaders) {
918
947
  if (!(_rhk in _streamHeaders)) _streamHeaders[_rhk] = _pendingHeaders[_rhk];
919
948
  }
920
949
  stream.respond(_streamHeaders);
921
950
  }
922
951
  stream.end(htmlContent);
923
- local.res.headersSent = true;
952
+ res.headersSent = true;
924
953
  }
925
954
  } else {
926
- local.res.end( htmlContent );
955
+ res.end( htmlContent );
927
956
  }
928
957
  layout = null;
929
958
  }
930
959
 
931
- // Release per-request refs save next first since local.next is used directly here.
932
- var _next = ( typeof(local.next) != 'undefined' ) ? local.next : null;
960
+ // Release per-request refs on the closure. The function-scoped
961
+ // `req` / `res` / `_next` captures stay alive until return and
962
+ // are GC'd then; the closure properties need explicit nulling
963
+ // for early memory release of the per-request payload.
933
964
  local.req = null;
934
965
  local.res = null;
935
966
  local.next = null;
@@ -966,7 +997,7 @@ module.exports = async function render(userData, displayInspector, errOptions, d
966
997
 
967
998
  if (hasViews() && isWithoutLayout) {
968
999
  // $.getScript(...)
969
- //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;
1000
+ //var isProxyHost = ( typeof(req.headers.host) != 'undefined' && localOptions.conf.server.scheme +'://'+ req.headers.host != localOptions.conf.hostname || typeof(req.headers[':authority']) != 'undefined' && localOptions.conf.server.scheme +'://'+ req.headers[':authority'] != localOptions.conf.hostname ) ? true : false;
970
1001
  //var hostname = (isProxyHost) ? localOptions.conf.hostname.replace(/\:\d+$/, '') : localOptions.conf.hostname;
971
1002
 
972
1003
 
@@ -1279,7 +1310,7 @@ module.exports = async function render(userData, displayInspector, errOptions, d
1279
1310
 
1280
1311
  if ( !headersSent() ) {
1281
1312
  // //catching errors
1282
- // local.res.statusCode = ( typeof(localOptions.conf.server.coreConfiguration.statusCodes[data.page.data.status]) != 'undefined' ) ? data.page.data.status : 200; // by default
1313
+ // res.statusCode = ( typeof(localOptions.conf.server.coreConfiguration.statusCodes[data.page.data.status]) != 'undefined' ) ? data.page.data.status : 200; // by default
1283
1314
 
1284
1315
  // // HTTP/2 (RFC7540 8.1.2.4):
1285
1316
  // // This standard for HTTP/2 explicitly states that status messages are not supported.
@@ -1298,14 +1329,14 @@ module.exports = async function render(userData, displayInspector, errOptions, d
1298
1329
  // ) {
1299
1330
 
1300
1331
  // try {
1301
- // local.res.statusMessage = localOptions.conf.server.coreConfiguration.statusCodes[data.page.data.status];
1332
+ // res.statusMessage = localOptions.conf.server.coreConfiguration.statusCodes[data.page.data.status];
1302
1333
  // } catch (err){
1303
- // local.res.statusCode = 500;
1304
- // local.res.statusMessage = err.stack||err.message||localOptions.conf.server.coreConfiguration.statusCodes[local.res.statusCode];
1334
+ // res.statusCode = 500;
1335
+ // res.statusMessage = err.stack||err.message||localOptions.conf.server.coreConfiguration.statusCodes[res.statusCode];
1305
1336
  // }
1306
1337
  // }
1307
1338
 
1308
- // local.res.setHeader('content-type', localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding );
1339
+ // res.setHeader('content-type', localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding );
1309
1340
 
1310
1341
  // try {
1311
1342
 
@@ -1318,7 +1349,7 @@ module.exports = async function render(userData, displayInspector, errOptions, d
1318
1349
  // } catch (err) {
1319
1350
  // filename = localOptions.template.html;
1320
1351
  // 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: '' );
1321
- // self.throwError(local.res, 500, new Error('Controller::render(...) compilation error encountered while trying to process template `'+ filename + '`\n' + (err.stack||err.message||err) ));
1352
+ // self.throwError(res, 500, new Error('Controller::render(...) compilation error encountered while trying to process template `'+ filename + '`\n' + (err.stack||err.message||err) ));
1322
1353
  // filename = null;
1323
1354
  // blacklistRe = null;
1324
1355
  // return;
@@ -1331,7 +1362,7 @@ module.exports = async function render(userData, displayInspector, errOptions, d
1331
1362
  var assets = null;
1332
1363
  try {
1333
1364
  // TODO - button in toolbar to empty url assets cache
1334
- if ( /** self.isCacheless() ||*/ typeof(localOptions.template.assets) == 'undefined' || typeof(localOptions.template.assets[local.req.url]) == 'undefined' ) {
1365
+ if ( /** self.isCacheless() ||*/ typeof(localOptions.template.assets) == 'undefined' || typeof(localOptions.template.assets[req.url]) == 'undefined' ) {
1335
1366
  // assets string -> object
1336
1367
  //assets = self.serverInstance.getAssets(localOptions.conf, layout.toString(), swig, data);
1337
1368
  assets = self.serverInstance.getAssets(localOptions.conf, layout, null, data);
@@ -1376,7 +1407,7 @@ module.exports = async function render(userData, displayInspector, errOptions, d
1376
1407
  if ( /\,$/.test(links) ) {
1377
1408
  links = links.substring(0, links.length-1);
1378
1409
  }
1379
- local.res.setHeader('link', links);
1410
+ res.setHeader('link', links);
1380
1411
  links = null;
1381
1412
  }
1382
1413
 
@@ -1384,14 +1415,24 @@ module.exports = async function render(userData, displayInspector, errOptions, d
1384
1415
 
1385
1416
  } catch (err) {
1386
1417
  assets = null;
1387
- self.throwError(local.res, 500, new Error('Controller::render(...) calling getAssets(...) \n' + (err.stack||err.message||err) ));
1418
+ self.throwError(res, 500, new Error('Controller::render(...) calling getAssets(...) \n' + (err.stack||err.message||err) ));
1388
1419
  return;
1389
1420
  }
1390
1421
  }
1391
1422
 
1392
1423
  if (newLayoutFilename) {
1393
1424
  // replaced: openSync/writeSync/closeSync — async write (#P31)
1394
- await fs.promises.writeFile(newLayoutFilename, layout);
1425
+ // Atomic write: temp file + rename. fs.promises.writeFile uses
1426
+ // O_TRUNC which transiently exposes a 0-byte state; a parallel
1427
+ // render reading the cached layout at the post-priming read
1428
+ // ~640 lines above could observe that empty state. Writing to
1429
+ // a temp file and renaming onto target is atomic on POSIX, so
1430
+ // readers always see either the prior content or the new
1431
+ // content.
1432
+ var _layoutTmpAssets = newLayoutFilename + '.tmp.' + process.pid + '.' + Date.now() + '.' + Math.random().toString(36).slice(2);
1433
+ await fs.promises.writeFile(_layoutTmpAssets, layout);
1434
+ await fs.promises.rename(_layoutTmpAssets, newLayoutFilename);
1435
+ _layoutTmpAssets = null;
1395
1436
  }
1396
1437
 
1397
1438
  // Last compilation before rendering
@@ -1445,30 +1486,30 @@ module.exports = async function render(userData, displayInspector, errOptions, d
1445
1486
  detail: (data.page.view.file || null)
1446
1487
  });
1447
1488
  }
1448
- local.res.setHeader('content-type', localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding );
1489
+ res.setHeader('content-type', localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding );
1449
1490
 
1450
1491
  if (
1451
1492
  !layoutCacheFailed
1452
1493
  && (
1453
1494
  !self.isCacheless()
1454
- && typeof(local.req.routing.cache) != 'undefined'
1455
- && local.req.method.toUpperCase() === 'GET'
1495
+ && typeof(req.routing.cache) != 'undefined'
1496
+ && req.method.toUpperCase() === 'GET'
1456
1497
  ||
1457
1498
  // allowing caching even for dev env
1458
1499
  String(self.serverInstance._cacheIsEnabled).toLowerCase() === 'true'
1459
- && typeof(local.req.routing.cache) != 'undefined'
1460
- && local.req.method.toUpperCase() === 'GET'
1500
+ && typeof(req.routing.cache) != 'undefined'
1501
+ && req.method.toUpperCase() === 'GET'
1461
1502
  )
1462
1503
  ) {
1463
- await writeCache(localOptions.bundle, localOptions.conf.server.cache, htmlContent);
1504
+ await writeCache(localOptions.bundle, localOptions.conf.server.cache, htmlContent, req, res);
1464
1505
  }
1465
1506
 
1466
1507
  // Cache-Control: miss path — inform browsers/CDNs of the response lifetime (#C6)
1467
- if ( typeof(local.req.routing.cache) != 'undefined' && local.req.routing.cache ) {
1468
- var _ccCfg = ( typeof(local.req.routing.cache) == 'string' ) ? { type: local.req.routing.cache } : local.req.routing.cache;
1508
+ if ( typeof(req.routing.cache) != 'undefined' && req.routing.cache ) {
1509
+ var _ccCfg = ( typeof(req.routing.cache) == 'string' ) ? { type: req.routing.cache } : req.routing.cache;
1469
1510
  var _ccTtl = ( typeof(_ccCfg.ttl) != 'undefined' && _ccCfg.ttl > 0 ) ? _ccCfg.ttl : localOptions.conf.server.cache.ttl;
1470
1511
  if ( _ccTtl > 0 ) {
1471
- local.res.setHeader('Cache-Control', ( _ccCfg.visibility === 'public' ? 'public' : 'private' ) + ', max-age=' + ~~(_ccTtl));
1512
+ res.setHeader('Cache-Control', ( _ccCfg.visibility === 'public' ? 'public' : 'private' ) + ', max-age=' + ~~(_ccTtl));
1472
1513
  }
1473
1514
  }
1474
1515
 
@@ -1505,60 +1546,60 @@ module.exports = async function render(userData, displayInspector, errOptions, d
1505
1546
  }
1506
1547
  }
1507
1548
 
1508
- console.info(local.req.method +' ['+local.res.statusCode +'] '+ local.req.url);
1549
+ console.info(req.method +' ['+res.statusCode +'] '+ req.url);
1509
1550
  // HEAD: send headers only — body suppressed (HTTP spec §4.3.2)
1510
- if ( /^HEAD$/i.test(local.req.method) ) {
1551
+ if ( /^HEAD$/i.test(req.method) ) {
1511
1552
  if ( stream ) {
1512
1553
  // #H8 — HTTP/2 HEAD: stream.respond() with content-length, no body.
1513
1554
  if ( !stream.headersSent ) {
1514
1555
  var _headH2 = {
1515
1556
  'content-type' : localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding,
1516
1557
  'content-length' : Buffer.byteLength(htmlContent, 'utf8'),
1517
- ':status' : local.res.statusCode || 200
1558
+ ':status' : res.statusCode || 200
1518
1559
  };
1519
- var _pendingH2 = local.res.getHeaders ? local.res.getHeaders() : {};
1560
+ var _pendingH2 = res.getHeaders ? res.getHeaders() : {};
1520
1561
  for (var _hk2 in _pendingH2) {
1521
1562
  if (!(_hk2 in _headH2)) _headH2[_hk2] = _pendingH2[_hk2];
1522
1563
  }
1523
1564
  stream.respond(_headH2);
1524
1565
  }
1525
1566
  stream.end();
1526
- local.res.headersSent = true;
1567
+ res.headersSent = true;
1527
1568
  } else {
1528
- local.res.setHeader('content-type', localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding);
1529
- local.res.setHeader('content-length', Buffer.byteLength(htmlContent, 'utf8'));
1530
- local.res.end();
1569
+ res.setHeader('content-type', localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding);
1570
+ res.setHeader('content-length', Buffer.byteLength(htmlContent, 'utf8'));
1571
+ res.end();
1531
1572
  }
1532
1573
  } else if ( stream ) {
1533
1574
  // #H8 — Direct HTTP/2 stream: bypass HTTP/1.1 compat layer.
1534
1575
  if (stream.destroyed || stream.closed) {
1535
- console.warn('[render-swig] Stream already destroyed — client disconnected before response was sent ('+ local.req.url +')');
1576
+ console.warn('[render-swig] Stream already destroyed — client disconnected before response was sent ('+ req.url +')');
1536
1577
  } else {
1537
1578
  if ( !stream.headersSent ) {
1538
1579
  var _streamHeaders2 = {
1539
1580
  'content-type' : localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding,
1540
- ':status' : local.res.statusCode || 200
1581
+ ':status' : res.statusCode || 200
1541
1582
  };
1542
- var _pendingHeaders2 = local.res.getHeaders ? local.res.getHeaders() : {};
1583
+ var _pendingHeaders2 = res.getHeaders ? res.getHeaders() : {};
1543
1584
  for (var _rhk2 in _pendingHeaders2) {
1544
1585
  if (!(_rhk2 in _streamHeaders2)) _streamHeaders2[_rhk2] = _pendingHeaders2[_rhk2];
1545
1586
  }
1546
1587
  stream.respond(_streamHeaders2);
1547
1588
  }
1548
1589
  stream.end(htmlContent);
1549
- local.res.headersSent = true;
1590
+ res.headersSent = true;
1550
1591
  }
1551
1592
  } else {
1552
- local.res.end( htmlContent );
1593
+ res.end( htmlContent );
1553
1594
  }
1554
1595
 
1555
1596
  layout = null;
1556
1597
  }
1557
1598
 
1558
- // console.info(local.req.method +' ['+local.res.statusCode +'] '+ local.req.url);
1599
+ // console.info(req.method +' ['+res.statusCode +'] '+ req.url);
1559
1600
 
1560
- // Release per-request refs save next first since local.next is used directly here.
1561
- var _next = ( typeof(local.next) != 'undefined' ) ? local.next : null;
1601
+ // Release per-request refs on the closure. The function-scoped
1602
+ // `req` / `res` / `_next` captures stay alive until return.
1562
1603
  local.req = null;
1563
1604
  local.res = null;
1564
1605
  local.next = null;
@@ -1567,32 +1608,32 @@ module.exports = async function render(userData, displayInspector, errOptions, d
1567
1608
  }
1568
1609
 
1569
1610
 
1570
- if ( typeof(local.req.params.errorObject) != 'undefined' ) {
1571
- return self.throwError(local.req.params.errorObject);
1611
+ if ( typeof(req.params.errorObject) != 'undefined' ) {
1612
+ return self.throwError(req.params.errorObject);
1572
1613
  }
1573
1614
  if ( stream ) {
1574
1615
  // #H8 — Direct HTTP/2 stream for error fallthrough.
1575
1616
  if (stream.destroyed || stream.closed) {
1576
- console.warn('[render-swig] Stream already destroyed — client disconnected before error response was sent ('+ (local.req ? local.req.url : 'unknown') +')');
1617
+ console.warn('[render-swig] Stream already destroyed — client disconnected before error response was sent ('+ (req ? req.url : 'unknown') +')');
1577
1618
  } else if ( !stream.headersSent ) {
1578
1619
  var _errHeaders = {
1579
1620
  'content-type' : localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding,
1580
1621
  ':status' : 500
1581
1622
  };
1582
- var _pendingErrH = local.res.getHeaders ? local.res.getHeaders() : {};
1623
+ var _pendingErrH = res.getHeaders ? res.getHeaders() : {};
1583
1624
  for (var _ehk in _pendingErrH) {
1584
1625
  if (!(_ehk in _errHeaders)) _errHeaders[_ehk] = _pendingErrH[_ehk];
1585
1626
  }
1586
1627
  stream.respond(_errHeaders);
1587
1628
  stream.end('Unexpected controller error while trying to render.');
1588
- local.res.headersSent = true;
1629
+ res.headersSent = true;
1589
1630
  }
1590
1631
  } else {
1591
- local.res.end('Unexpected controller error while trying to render.');
1632
+ res.end('Unexpected controller error while trying to render.');
1592
1633
  }
1593
1634
 
1594
- // Release per-request refs save next first since local.next is used directly here.
1595
- var _next = ( typeof(local.next) != 'undefined' ) ? local.next : null;
1635
+ // Release per-request refs on the closure. The function-scoped
1636
+ // `req` / `res` / `_next` captures stay alive until return.
1596
1637
  local.req = null;
1597
1638
  local.res = null;
1598
1639
  local.next = null;
@@ -1600,6 +1641,6 @@ module.exports = async function render(userData, displayInspector, errOptions, d
1600
1641
  return;
1601
1642
 
1602
1643
  } catch (err) {
1603
- return self.throwError(local.res, 500, err);
1644
+ return self.throwError(res, 500, err);
1604
1645
  }
1605
1646
  };