gina 0.6.7 → 0.6.8

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 (583) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +27 -26
  3. package/ROADMAP.md +3 -2
  4. package/framework/v0.6.8/VERSION +1 -0
  5. package/framework/{v0.6.7 → v0.6.8}/core/config.js +10 -0
  6. package/framework/v0.6.8/core/connectors/couchbase/lib/storage-store.js +1074 -0
  7. package/framework/{v0.6.7 → v0.6.8}/core/controller/controller.js +532 -22
  8. package/framework/v0.6.8/core/controller/controller.render-stream.js +270 -0
  9. package/framework/{v0.6.7 → v0.6.8}/core/gna.js +10 -2
  10. package/framework/{v0.6.7 → v0.6.8}/core/router.js +30 -10
  11. package/framework/{v0.6.7 → v0.6.8}/core/server.isaac.js +42 -7
  12. package/framework/{v0.6.7 → v0.6.8}/lib/cmd/storage/gc.js +6 -0
  13. package/framework/{v0.6.7 → v0.6.8}/lib/cmd/storage/stats.js +7 -0
  14. package/framework/{v0.6.7 → v0.6.8}/lib/cmd/storage/verify.js +6 -0
  15. package/framework/{v0.6.7 → v0.6.8}/lib/storage/src/local-cas.js +107 -9
  16. package/framework/v0.6.8/lib/storage/src/local-stream.js +1418 -0
  17. package/framework/{v0.6.7 → v0.6.8}/lib/storage/src/local.js +177 -16
  18. package/framework/{v0.6.7 → v0.6.8}/lib/storage/src/main.js +406 -25
  19. package/framework/{v0.6.7 → v0.6.8}/lib/storage/src/meta-store.js +13 -2
  20. package/framework/v0.6.8/lib/storage/src/s3.js +759 -0
  21. package/framework/{v0.6.7 → v0.6.8}/lib/storage/src/util.js +26 -1
  22. package/framework/{v0.6.7 → v0.6.8}/lib/storage-store.js +33 -23
  23. package/framework/{v0.6.7 → v0.6.8}/package.json +1 -1
  24. package/gna.js +4 -4
  25. package/llms.txt +22 -47
  26. package/package.json +3 -3
  27. package/schema/routing.json +4 -0
  28. package/schema/settings.json +84 -10
  29. package/script/check_no_local_leak.js +2 -1
  30. package/script/retry_lockfile_sync.js +2 -1
  31. package/script/soak/storage-couchbase/README.md +61 -0
  32. package/script/soak/storage-couchbase/probe-cas.js +77 -0
  33. package/script/soak/storage-couchbase/probe-store.js +101 -0
  34. package/types/index.d.ts +18 -0
  35. package/framework/v0.6.7/VERSION +0 -1
  36. package/framework/v0.6.7/core/controller/controller.render-stream.js +0 -169
  37. /package/framework/{v0.6.7 → v0.6.8}/AUTHORS +0 -0
  38. /package/framework/{v0.6.7 → v0.6.8}/LICENSE +0 -0
  39. /package/framework/{v0.6.7 → v0.6.8}/core/asset/html/nolayout.html +0 -0
  40. /package/framework/{v0.6.7 → v0.6.8}/core/asset/html/static.html +0 -0
  41. /package/framework/{v0.6.7 → v0.6.8}/core/asset/img/android-chrome-192x192.png +0 -0
  42. /package/framework/{v0.6.7 → v0.6.8}/core/asset/img/android-chrome-512x512.png +0 -0
  43. /package/framework/{v0.6.7 → v0.6.8}/core/asset/img/apple-touch-icon.png +0 -0
  44. /package/framework/{v0.6.7 → v0.6.8}/core/asset/img/favicon-16x16.png +0 -0
  45. /package/framework/{v0.6.7 → v0.6.8}/core/asset/img/favicon-32x32.png +0 -0
  46. /package/framework/{v0.6.7 → v0.6.8}/core/asset/img/favicon.ico +0 -0
  47. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/README.md +0 -0
  48. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.css +0 -0
  49. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.js +0 -0
  50. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/beemaster/index.html +0 -0
  51. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/css/gina.min.css +0 -0
  52. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.br +0 -0
  53. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.gz +0 -0
  54. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/html/statusbar.html +0 -0
  55. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.br +0 -0
  56. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.gz +0 -0
  57. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/inspector/have_heart_one-webfont.woff2 +0 -0
  58. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/inspector/index.html +0 -0
  59. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/inspector/inspector.css +0 -0
  60. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/inspector/inspector.js +0 -0
  61. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/inspector/logo.svg +0 -0
  62. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/js/gina.js +0 -0
  63. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/js/gina.min.js +0 -0
  64. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
  65. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
  66. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js +0 -0
  67. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.br +0 -0
  68. /package/framework/{v0.6.7 → v0.6.8}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.gz +0 -0
  69. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/ai/index.js +0 -0
  70. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/ai/lib/connector.js +0 -0
  71. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/couchbase/index.js +0 -0
  72. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/couchbase/lib/connector.js +0 -0
  73. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/couchbase/lib/connector.v3.js +0 -0
  74. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/couchbase/lib/connector.v4.js +0 -0
  75. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/couchbase/lib/n1ql.js +0 -0
  76. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/couchbase/lib/session-store.js +0 -0
  77. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/couchbase/lib/session-store.v3.js +0 -0
  78. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/couchbase/lib/session-store.v4.js +0 -0
  79. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/duckdb/index.js +0 -0
  80. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/duckdb/lib/connector.js +0 -0
  81. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/mongodb/index.js +0 -0
  82. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/mongodb/lib/connector.js +0 -0
  83. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/mongodb/lib/job-store.js +0 -0
  84. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/mongodb/lib/pipeline-loader.js +0 -0
  85. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/mongodb/lib/session-store.js +0 -0
  86. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/mysql/index.js +0 -0
  87. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/mysql/lib/connector.js +0 -0
  88. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/param-redact.js +0 -0
  89. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/postgresql/index.js +0 -0
  90. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/postgresql/lib/connector.js +0 -0
  91. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/redis/index.js +0 -0
  92. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/redis/lib/connector.js +0 -0
  93. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/redis/lib/job-store.js +0 -0
  94. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/redis/lib/render-cache-store.js +0 -0
  95. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/redis/lib/session-store.js +0 -0
  96. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/scylladb/index.js +0 -0
  97. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/scylladb/lib/connector.js +0 -0
  98. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/scylladb/lib/session-store.js +0 -0
  99. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/sql-parser.js +0 -0
  100. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/sqlite/index.js +0 -0
  101. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/sqlite/lib/connector.js +0 -0
  102. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/sqlite/lib/job-store.js +0 -0
  103. /package/framework/{v0.6.7 → v0.6.8}/core/connectors/sqlite/lib/session-store.js +0 -0
  104. /package/framework/{v0.6.7 → v0.6.8}/core/content.encoding +0 -0
  105. /package/framework/{v0.6.7 → v0.6.8}/core/controller/controller.framework.js +0 -0
  106. /package/framework/{v0.6.7 → v0.6.8}/core/controller/controller.render-json.js +0 -0
  107. /package/framework/{v0.6.7 → v0.6.8}/core/controller/controller.render-nunjucks-async.js +0 -0
  108. /package/framework/{v0.6.7 → v0.6.8}/core/controller/controller.render-nunjucks.js +0 -0
  109. /package/framework/{v0.6.7 → v0.6.8}/core/controller/controller.render-swig-async.js +0 -0
  110. /package/framework/{v0.6.7 → v0.6.8}/core/controller/controller.render-swig.js +0 -0
  111. /package/framework/{v0.6.7 → v0.6.8}/core/controller/controller.render-v1.js +0 -0
  112. /package/framework/{v0.6.7 → v0.6.8}/core/controller/index.js +0 -0
  113. /package/framework/{v0.6.7 → v0.6.8}/core/controller/inspector-window-emit.js +0 -0
  114. /package/framework/{v0.6.7 → v0.6.8}/core/controller/release-banner.js +0 -0
  115. /package/framework/{v0.6.7 → v0.6.8}/core/dev/index.js +0 -0
  116. /package/framework/{v0.6.7 → v0.6.8}/core/dev/lib/class.js +0 -0
  117. /package/framework/{v0.6.7 → v0.6.8}/core/dev/lib/factory.js +0 -0
  118. /package/framework/{v0.6.7 → v0.6.8}/core/dev/lib/tools.js +0 -0
  119. /package/framework/{v0.6.7 → v0.6.8}/core/locales/README.md +0 -0
  120. /package/framework/{v0.6.7 → v0.6.8}/core/locales/currency.json +0 -0
  121. /package/framework/{v0.6.7 → v0.6.8}/core/locales/dist/language/en.json +0 -0
  122. /package/framework/{v0.6.7 → v0.6.8}/core/locales/dist/language/fr.json +0 -0
  123. /package/framework/{v0.6.7 → v0.6.8}/core/locales/dist/region/en.json +0 -0
  124. /package/framework/{v0.6.7 → v0.6.8}/core/locales/dist/region/fr.json +0 -0
  125. /package/framework/{v0.6.7 → v0.6.8}/core/locales/index.js +0 -0
  126. /package/framework/{v0.6.7 → v0.6.8}/core/mime.types +0 -0
  127. /package/framework/{v0.6.7 → v0.6.8}/core/model/entity.js +0 -0
  128. /package/framework/{v0.6.7 → v0.6.8}/core/model/index.js +0 -0
  129. /package/framework/{v0.6.7 → v0.6.8}/core/model/template/entityFactory.js +0 -0
  130. /package/framework/{v0.6.7 → v0.6.8}/core/model/template/index.js +0 -0
  131. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/README.md +0 -0
  132. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/index.js +0 -0
  133. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/csrf/README.md +0 -0
  134. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/csrf/package.json +0 -0
  135. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/csrf/src/main.js +0 -0
  136. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/README.md +0 -0
  137. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/coep/README.md +0 -0
  138. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/coep/package.json +0 -0
  139. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/coep/src/main.js +0 -0
  140. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/coop/README.md +0 -0
  141. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/coop/package.json +0 -0
  142. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/coop/src/main.js +0 -0
  143. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/corp/README.md +0 -0
  144. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/corp/package.json +0 -0
  145. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/corp/src/main.js +0 -0
  146. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/csp/README.md +0 -0
  147. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/csp/package.json +0 -0
  148. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/csp/src/main.js +0 -0
  149. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/hide-powered-by/README.md +0 -0
  150. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/hide-powered-by/package.json +0 -0
  151. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/hide-powered-by/src/main.js +0 -0
  152. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/hsts/README.md +0 -0
  153. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/hsts/package.json +0 -0
  154. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/hsts/src/main.js +0 -0
  155. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/origin-agent-cluster/README.md +0 -0
  156. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/origin-agent-cluster/package.json +0 -0
  157. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/origin-agent-cluster/src/main.js +0 -0
  158. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/package.json +0 -0
  159. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/referrer-policy/README.md +0 -0
  160. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/referrer-policy/package.json +0 -0
  161. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/referrer-policy/src/main.js +0 -0
  162. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/src/main.js +0 -0
  163. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-content-type-options/README.md +0 -0
  164. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-content-type-options/package.json +0 -0
  165. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-content-type-options/src/main.js +0 -0
  166. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-dns-prefetch-control/README.md +0 -0
  167. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-dns-prefetch-control/package.json +0 -0
  168. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-dns-prefetch-control/src/main.js +0 -0
  169. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-download-options/README.md +0 -0
  170. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-download-options/package.json +0 -0
  171. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-download-options/src/main.js +0 -0
  172. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-frame-options/README.md +0 -0
  173. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-frame-options/package.json +0 -0
  174. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-frame-options/src/main.js +0 -0
  175. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/README.md +0 -0
  176. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/package.json +0 -0
  177. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/src/main.js +0 -0
  178. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-xss-protection/README.md +0 -0
  179. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-xss-protection/package.json +0 -0
  180. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/security-headers/x-xss-protection/src/main.js +0 -0
  181. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/session/README.md +0 -0
  182. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/session/package.json +0 -0
  183. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/session/src/main.js +0 -0
  184. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/storage/README.md +0 -0
  185. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/storage/build.json +0 -0
  186. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/storage/package.json +0 -0
  187. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/storage/src/main.js +0 -0
  188. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/validator/README.md +0 -0
  189. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/validator/build.json +0 -0
  190. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/validator/package.json +0 -0
  191. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/validator/src/form-validator.js +0 -0
  192. /package/framework/{v0.6.7 → v0.6.8}/core/plugins/lib/validator/src/main.js +0 -0
  193. /package/framework/{v0.6.7 → v0.6.8}/core/server.express.js +0 -0
  194. /package/framework/{v0.6.7 → v0.6.8}/core/server.js +0 -0
  195. /package/framework/{v0.6.7 → v0.6.8}/core/status.codes +0 -0
  196. /package/framework/{v0.6.7 → v0.6.8}/core/template/_gitignore +0 -0
  197. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle/config/app.json +0 -0
  198. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle/config/connectors.json +0 -0
  199. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle/config/routing.json +0 -0
  200. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle/config/settings.json +0 -0
  201. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle/config/settings.server.json +0 -0
  202. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle/config/templates.json +0 -0
  203. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle/config/watchers.json +0 -0
  204. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle/controllers/controller.content.js +0 -0
  205. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle/controllers/controller.js +0 -0
  206. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle/controllers/setup.js +0 -0
  207. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle/index.js +0 -0
  208. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle/locales/en.json +0 -0
  209. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle_namespace/controllers/controller.js +0 -0
  210. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle_public/css/default.css +0 -0
  211. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle_public/css/home.css +0 -0
  212. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle_public/css/vendor/readme.md +0 -0
  213. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle_public/favicon.ico +0 -0
  214. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle_public/js/components/x-checklist.js +0 -0
  215. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle_public/js/vendor/readme.md +0 -0
  216. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle_public/manifest.webmanifest +0 -0
  217. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle_public/readme.md +0 -0
  218. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle_public/sw.js +0 -0
  219. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle_templates/handlers/main.js +0 -0
  220. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle_templates/html/content/homepage.html +0 -0
  221. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle_templates/html/includes/error-msg-noscript.html +0 -0
  222. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle_templates/html/includes/error-msg-outdated-browser.html +0 -0
  223. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle_templates/html/includes/x-checklist.html +0 -0
  224. /package/framework/{v0.6.7 → v0.6.8}/core/template/boilerplate/bundle_templates/html/layouts/main.html +0 -0
  225. /package/framework/{v0.6.7 → v0.6.8}/core/template/command/gina.bat.tpl +0 -0
  226. /package/framework/{v0.6.7 → v0.6.8}/core/template/command/gina.tpl +0 -0
  227. /package/framework/{v0.6.7 → v0.6.8}/core/template/conf/env.json +0 -0
  228. /package/framework/{v0.6.7 → v0.6.8}/core/template/conf/manifest.json +0 -0
  229. /package/framework/{v0.6.7 → v0.6.8}/core/template/conf/package.json +0 -0
  230. /package/framework/{v0.6.7 → v0.6.8}/core/template/conf/settings.json +0 -0
  231. /package/framework/{v0.6.7 → v0.6.8}/core/template/conf/statics.json +0 -0
  232. /package/framework/{v0.6.7 → v0.6.8}/core/template/conf/templates.json +0 -0
  233. /package/framework/{v0.6.7 → v0.6.8}/core/template/error/client/json/401.json +0 -0
  234. /package/framework/{v0.6.7 → v0.6.8}/core/template/error/client/json/403.json +0 -0
  235. /package/framework/{v0.6.7 → v0.6.8}/core/template/error/client/json/404.json +0 -0
  236. /package/framework/{v0.6.7 → v0.6.8}/core/template/error/server/html/50x.html +0 -0
  237. /package/framework/{v0.6.7 → v0.6.8}/core/template/error/server/json/500.json +0 -0
  238. /package/framework/{v0.6.7 → v0.6.8}/core/template/error/server/json/503.json +0 -0
  239. /package/framework/{v0.6.7 → v0.6.8}/core/template/extensions/logger/config.json +0 -0
  240. /package/framework/{v0.6.7 → v0.6.8}/helpers/console.js +0 -0
  241. /package/framework/{v0.6.7 → v0.6.8}/helpers/context.js +0 -0
  242. /package/framework/{v0.6.7 → v0.6.8}/helpers/data/LICENSE +0 -0
  243. /package/framework/{v0.6.7 → v0.6.8}/helpers/data/README.md +0 -0
  244. /package/framework/{v0.6.7 → v0.6.8}/helpers/data/package.json +0 -0
  245. /package/framework/{v0.6.7 → v0.6.8}/helpers/data/src/main.js +0 -0
  246. /package/framework/{v0.6.7 → v0.6.8}/helpers/dateFormat.js +0 -0
  247. /package/framework/{v0.6.7 → v0.6.8}/helpers/index.js +0 -0
  248. /package/framework/{v0.6.7 → v0.6.8}/helpers/json/LICENSE +0 -0
  249. /package/framework/{v0.6.7 → v0.6.8}/helpers/json/README.md +0 -0
  250. /package/framework/{v0.6.7 → v0.6.8}/helpers/json/package.json +0 -0
  251. /package/framework/{v0.6.7 → v0.6.8}/helpers/json/src/main.js +0 -0
  252. /package/framework/{v0.6.7 → v0.6.8}/helpers/path.js +0 -0
  253. /package/framework/{v0.6.7 → v0.6.8}/helpers/plugins/README.md +0 -0
  254. /package/framework/{v0.6.7 → v0.6.8}/helpers/plugins/package.json +0 -0
  255. /package/framework/{v0.6.7 → v0.6.8}/helpers/plugins/src/api-error.js +0 -0
  256. /package/framework/{v0.6.7 → v0.6.8}/helpers/plugins/src/main.js +0 -0
  257. /package/framework/{v0.6.7 → v0.6.8}/helpers/prototypes.js +0 -0
  258. /package/framework/{v0.6.7 → v0.6.8}/helpers/task.js +0 -0
  259. /package/framework/{v0.6.7 → v0.6.8}/helpers/text.js +0 -0
  260. /package/framework/{v0.6.7 → v0.6.8}/lib/admin/package.json +0 -0
  261. /package/framework/{v0.6.7 → v0.6.8}/lib/admin/src/main.js +0 -0
  262. /package/framework/{v0.6.7 → v0.6.8}/lib/archiver/README.md +0 -0
  263. /package/framework/{v0.6.7 → v0.6.8}/lib/archiver/build.json +0 -0
  264. /package/framework/{v0.6.7 → v0.6.8}/lib/archiver/package.json +0 -0
  265. /package/framework/{v0.6.7 → v0.6.8}/lib/archiver/src/dep/jszip.min.js +0 -0
  266. /package/framework/{v0.6.7 → v0.6.8}/lib/archiver/src/main.js +0 -0
  267. /package/framework/{v0.6.7 → v0.6.8}/lib/async/package.json +0 -0
  268. /package/framework/{v0.6.7 → v0.6.8}/lib/async/src/main.js +0 -0
  269. /package/framework/{v0.6.7 → v0.6.8}/lib/audit/package.json +0 -0
  270. /package/framework/{v0.6.7 → v0.6.8}/lib/audit/src/main.js +0 -0
  271. /package/framework/{v0.6.7 → v0.6.8}/lib/audit-store.js +0 -0
  272. /package/framework/{v0.6.7 → v0.6.8}/lib/authn/package.json +0 -0
  273. /package/framework/{v0.6.7 → v0.6.8}/lib/authn/src/lockout.js +0 -0
  274. /package/framework/{v0.6.7 → v0.6.8}/lib/authn/src/main.js +0 -0
  275. /package/framework/{v0.6.7 → v0.6.8}/lib/authn/src/totp.js +0 -0
  276. /package/framework/{v0.6.7 → v0.6.8}/lib/authz-gate/package.json +0 -0
  277. /package/framework/{v0.6.7 → v0.6.8}/lib/authz-gate/src/main.js +0 -0
  278. /package/framework/{v0.6.7 → v0.6.8}/lib/cache/README.md +0 -0
  279. /package/framework/{v0.6.7 → v0.6.8}/lib/cache/build.json +0 -0
  280. /package/framework/{v0.6.7 → v0.6.8}/lib/cache/package.json +0 -0
  281. /package/framework/{v0.6.7 → v0.6.8}/lib/cache/src/main.js +0 -0
  282. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/aliases.json +0 -0
  283. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/audit/arguments.json +0 -0
  284. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/audit/help.txt +0 -0
  285. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/audit/verify.js +0 -0
  286. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/add.js +0 -0
  287. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/arguments.json +0 -0
  288. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/build.js +0 -0
  289. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/copy.js +0 -0
  290. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/cp.js +0 -0
  291. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/help.js +0 -0
  292. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/help.txt +0 -0
  293. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/inc/name-rewrite.js +0 -0
  294. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/list.js +0 -0
  295. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/man.js +0 -0
  296. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/mcp-start.js +0 -0
  297. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/mcp.js +0 -0
  298. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/oas.js +0 -0
  299. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/openapi.js +0 -0
  300. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/remove.js +0 -0
  301. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/rename.js +0 -0
  302. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/restart.js +0 -0
  303. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/rm.js +0 -0
  304. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/start.js +0 -0
  305. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/status.js +0 -0
  306. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/stop.js +0 -0
  307. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/bundle/types.js +0 -0
  308. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/cache/arguments.json +0 -0
  309. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/cache/clear.js +0 -0
  310. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/cache/help.txt +0 -0
  311. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/cache/stats.js +0 -0
  312. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/connector/add.js +0 -0
  313. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/connector/arguments.json +0 -0
  314. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/connector/help.js +0 -0
  315. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/connector/help.txt +0 -0
  316. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/connector/infer.js +0 -0
  317. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/connector/list.js +0 -0
  318. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/connector/migrate.js +0 -0
  319. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/connector/models.js +0 -0
  320. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/connector/remove.js +0 -0
  321. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/connector/rm.js +0 -0
  322. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/connector/test.js +0 -0
  323. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/container/arguments.json +0 -0
  324. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/container/help.js +0 -0
  325. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/container/help.txt +0 -0
  326. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/container/man.js +0 -0
  327. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/container/ps.js +0 -0
  328. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/container/stop.js +0 -0
  329. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/controller/add.js +0 -0
  330. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/controller/arguments.json +0 -0
  331. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/controller/help.txt +0 -0
  332. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/controller/inc/args.js +0 -0
  333. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/controller/inc/namespace.js +0 -0
  334. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/controller/inc/reference-rewrite.js +0 -0
  335. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/controller/inc/reference-scan.js +0 -0
  336. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/controller/inc/scaffold.js +0 -0
  337. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/controller/remove.js +0 -0
  338. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/controller/rename.js +0 -0
  339. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/controller/rm.js +0 -0
  340. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/env/add.js +0 -0
  341. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/env/get.js +0 -0
  342. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/env/help.js +0 -0
  343. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/env/help.txt +0 -0
  344. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/env/link-dev.js +0 -0
  345. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/env/list.js +0 -0
  346. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/env/remove.js +0 -0
  347. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/env/rm.js +0 -0
  348. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/env/set.js +0 -0
  349. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/env/unset.js +0 -0
  350. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/env/use.js +0 -0
  351. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/add.js +0 -0
  352. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/arguments.json +0 -0
  353. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/build.js +0 -0
  354. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/dot.js +0 -0
  355. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/get.js +0 -0
  356. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/help.js +0 -0
  357. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/help.txt +0 -0
  358. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/init.js +0 -0
  359. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/link-node-modules.js +0 -0
  360. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/link.js +0 -0
  361. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/list.js +0 -0
  362. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/man.js +0 -0
  363. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/msg.json +0 -0
  364. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/open.js +0 -0
  365. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/remove.js +0 -0
  366. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/reset.js +0 -0
  367. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/restart.js +0 -0
  368. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/set.js +0 -0
  369. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/start.js +0 -0
  370. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/status.js +0 -0
  371. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/stop.js +0 -0
  372. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/tail.js +0 -0
  373. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/update.js +0 -0
  374. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/framework/version.js +0 -0
  375. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/gina-dev.1.md +0 -0
  376. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/gina-framework.1.md +0 -0
  377. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/gina.1.md +0 -0
  378. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/helper.js +0 -0
  379. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/i18n/add.js +0 -0
  380. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/i18n/arguments.json +0 -0
  381. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/i18n/export.js +0 -0
  382. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/i18n/help.js +0 -0
  383. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/i18n/help.txt +0 -0
  384. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/i18n/import.js +0 -0
  385. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/i18n/scan.js +0 -0
  386. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/image/_host.js +0 -0
  387. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/image/arguments.json +0 -0
  388. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/image/build.js +0 -0
  389. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/image/help.js +0 -0
  390. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/image/help.txt +0 -0
  391. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/image/list.js +0 -0
  392. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/image/man.js +0 -0
  393. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/image/rm.js +0 -0
  394. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/image/run.js +0 -0
  395. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/index.js +0 -0
  396. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/inspector/help.js +0 -0
  397. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/inspector/help.txt +0 -0
  398. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/inspector/open.js +0 -0
  399. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/man-render.js +0 -0
  400. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/minion/arguments.json +0 -0
  401. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/minion/help.js +0 -0
  402. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/minion/help.txt +0 -0
  403. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/minion/kill.js +0 -0
  404. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/minion/list.js +0 -0
  405. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/msg.json +0 -0
  406. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/port/help.js +0 -0
  407. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/port/help.txt +0 -0
  408. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/port/inc/scan.js +0 -0
  409. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/port/list.js +0 -0
  410. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/port/reset.js +0 -0
  411. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/port/set.js +0 -0
  412. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/add.js +0 -0
  413. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/arguments.json +0 -0
  414. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/backup.js +0 -0
  415. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/build.js +0 -0
  416. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/help.js +0 -0
  417. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/help.txt +0 -0
  418. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/import.js +0 -0
  419. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/list.js +0 -0
  420. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/man.js +0 -0
  421. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/move.js +0 -0
  422. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/remove.js +0 -0
  423. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/rename.js +0 -0
  424. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/restart.js +0 -0
  425. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/restore.js +0 -0
  426. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/rm.js +0 -0
  427. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/start.js +0 -0
  428. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/status.js +0 -0
  429. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/project/stop.js +0 -0
  430. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/protocol/arguments.json +0 -0
  431. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/protocol/help.js +0 -0
  432. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/protocol/help.txt +0 -0
  433. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/protocol/list.js +0 -0
  434. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/protocol/remove.js +0 -0
  435. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/protocol/set.js +0 -0
  436. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/scope/add.js +0 -0
  437. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/scope/help.js +0 -0
  438. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/scope/help.txt +0 -0
  439. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/scope/link-local.js +0 -0
  440. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/scope/link-production.js +0 -0
  441. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/scope/list.js +0 -0
  442. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/scope/remove.js +0 -0
  443. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/scope/rm.js +0 -0
  444. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/scope/use.js +0 -0
  445. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/secrets/arguments.json +0 -0
  446. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/secrets/check.js +0 -0
  447. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/secrets/help.js +0 -0
  448. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/secrets/help.txt +0 -0
  449. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/secrets/scan.js +0 -0
  450. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/service/help.js +0 -0
  451. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/service/help.txt +0 -0
  452. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/service/list.js +0 -0
  453. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/service/man.js +0 -0
  454. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/service/start.js +0 -0
  455. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/storage/arguments.json +0 -0
  456. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/storage/help.txt +0 -0
  457. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd/view/add.js +0 -0
  458. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd-status-format/package.json +0 -0
  459. /package/framework/{v0.6.7 → v0.6.8}/lib/cmd-status-format/src/main.js +0 -0
  460. /package/framework/{v0.6.7 → v0.6.8}/lib/collection/README.md +0 -0
  461. /package/framework/{v0.6.7 → v0.6.8}/lib/collection/build.json +0 -0
  462. /package/framework/{v0.6.7 → v0.6.8}/lib/collection/package.json +0 -0
  463. /package/framework/{v0.6.7 → v0.6.8}/lib/collection/src/main.js +0 -0
  464. /package/framework/{v0.6.7 → v0.6.8}/lib/config.js +0 -0
  465. /package/framework/{v0.6.7 → v0.6.8}/lib/connector-config/package.json +0 -0
  466. /package/framework/{v0.6.7 → v0.6.8}/lib/connector-config/src/main.js +0 -0
  467. /package/framework/{v0.6.7 → v0.6.8}/lib/connector-error/package.json +0 -0
  468. /package/framework/{v0.6.7 → v0.6.8}/lib/connector-error/src/main.js +0 -0
  469. /package/framework/{v0.6.7 → v0.6.8}/lib/connector-registry/package.json +0 -0
  470. /package/framework/{v0.6.7 → v0.6.8}/lib/connector-registry/src/main.js +0 -0
  471. /package/framework/{v0.6.7 → v0.6.8}/lib/cron/README.md +0 -0
  472. /package/framework/{v0.6.7 → v0.6.8}/lib/cron/package.json +0 -0
  473. /package/framework/{v0.6.7 → v0.6.8}/lib/cron/src/main.js +0 -0
  474. /package/framework/{v0.6.7 → v0.6.8}/lib/domain/LICENSE +0 -0
  475. /package/framework/{v0.6.7 → v0.6.8}/lib/domain/README.md +0 -0
  476. /package/framework/{v0.6.7 → v0.6.8}/lib/domain/package.json +0 -0
  477. /package/framework/{v0.6.7 → v0.6.8}/lib/domain/src/main.js +0 -0
  478. /package/framework/{v0.6.7 → v0.6.8}/lib/dto/package.json +0 -0
  479. /package/framework/{v0.6.7 → v0.6.8}/lib/dto/src/main.js +0 -0
  480. /package/framework/{v0.6.7 → v0.6.8}/lib/dto-pipe/package.json +0 -0
  481. /package/framework/{v0.6.7 → v0.6.8}/lib/dto-pipe/src/main.js +0 -0
  482. /package/framework/{v0.6.7 → v0.6.8}/lib/dto-types/package.json +0 -0
  483. /package/framework/{v0.6.7 → v0.6.8}/lib/dto-types/src/main.js +0 -0
  484. /package/framework/{v0.6.7 → v0.6.8}/lib/generator/index.js +0 -0
  485. /package/framework/{v0.6.7 → v0.6.8}/lib/i18n/package.json +0 -0
  486. /package/framework/{v0.6.7 → v0.6.8}/lib/i18n/src/main.js +0 -0
  487. /package/framework/{v0.6.7 → v0.6.8}/lib/image-build/package.json +0 -0
  488. /package/framework/{v0.6.7 → v0.6.8}/lib/image-build/src/main.js +0 -0
  489. /package/framework/{v0.6.7 → v0.6.8}/lib/index.js +0 -0
  490. /package/framework/{v0.6.7 → v0.6.8}/lib/inherits/LICENSE +0 -0
  491. /package/framework/{v0.6.7 → v0.6.8}/lib/inherits/README.md +0 -0
  492. /package/framework/{v0.6.7 → v0.6.8}/lib/inherits/package.json +0 -0
  493. /package/framework/{v0.6.7 → v0.6.8}/lib/inherits/src/main.js +0 -0
  494. /package/framework/{v0.6.7 → v0.6.8}/lib/inspector-events/package.json +0 -0
  495. /package/framework/{v0.6.7 → v0.6.8}/lib/inspector-events/src/main.js +0 -0
  496. /package/framework/{v0.6.7 → v0.6.8}/lib/inspector-redact/package.json +0 -0
  497. /package/framework/{v0.6.7 → v0.6.8}/lib/inspector-redact/src/main.js +0 -0
  498. /package/framework/{v0.6.7 → v0.6.8}/lib/instrument/package.json +0 -0
  499. /package/framework/{v0.6.7 → v0.6.8}/lib/instrument/src/main.js +0 -0
  500. /package/framework/{v0.6.7 → v0.6.8}/lib/job/package.json +0 -0
  501. /package/framework/{v0.6.7 → v0.6.8}/lib/job/src/main.js +0 -0
  502. /package/framework/{v0.6.7 → v0.6.8}/lib/job-store.js +0 -0
  503. /package/framework/{v0.6.7 → v0.6.8}/lib/json-config-header/package.json +0 -0
  504. /package/framework/{v0.6.7 → v0.6.8}/lib/json-config-header/src/main.js +0 -0
  505. /package/framework/{v0.6.7 → v0.6.8}/lib/loading-state/package.json +0 -0
  506. /package/framework/{v0.6.7 → v0.6.8}/lib/loading-state/src/main.js +0 -0
  507. /package/framework/{v0.6.7 → v0.6.8}/lib/logger/README.md +0 -0
  508. /package/framework/{v0.6.7 → v0.6.8}/lib/logger/package.json +0 -0
  509. /package/framework/{v0.6.7 → v0.6.8}/lib/logger/src/containers/default/index.js +0 -0
  510. /package/framework/{v0.6.7 → v0.6.8}/lib/logger/src/containers/file/index.js +0 -0
  511. /package/framework/{v0.6.7 → v0.6.8}/lib/logger/src/containers/file/lib/logrotator/README.md +0 -0
  512. /package/framework/{v0.6.7 → v0.6.8}/lib/logger/src/containers/file/lib/logrotator/index.js +0 -0
  513. /package/framework/{v0.6.7 → v0.6.8}/lib/logger/src/containers/mq/index.js +0 -0
  514. /package/framework/{v0.6.7 → v0.6.8}/lib/logger/src/containers/mq/listener.js +0 -0
  515. /package/framework/{v0.6.7 → v0.6.8}/lib/logger/src/containers/mq/speaker.js +0 -0
  516. /package/framework/{v0.6.7 → v0.6.8}/lib/logger/src/helper.js +0 -0
  517. /package/framework/{v0.6.7 → v0.6.8}/lib/logger/src/main.js +0 -0
  518. /package/framework/{v0.6.7 → v0.6.8}/lib/math/index.js +0 -0
  519. /package/framework/{v0.6.7 → v0.6.8}/lib/mcp-dispatch/package.json +0 -0
  520. /package/framework/{v0.6.7 → v0.6.8}/lib/mcp-dispatch/src/main.js +0 -0
  521. /package/framework/{v0.6.7 → v0.6.8}/lib/mcp-http/package.json +0 -0
  522. /package/framework/{v0.6.7 → v0.6.8}/lib/mcp-http/src/main.js +0 -0
  523. /package/framework/{v0.6.7 → v0.6.8}/lib/mcp-server/package.json +0 -0
  524. /package/framework/{v0.6.7 → v0.6.8}/lib/mcp-server/src/main.js +0 -0
  525. /package/framework/{v0.6.7 → v0.6.8}/lib/merge/README.md +0 -0
  526. /package/framework/{v0.6.7 → v0.6.8}/lib/merge/package.json +0 -0
  527. /package/framework/{v0.6.7 → v0.6.8}/lib/merge/src/main.js +0 -0
  528. /package/framework/{v0.6.7 → v0.6.8}/lib/metrics/package.json +0 -0
  529. /package/framework/{v0.6.7 → v0.6.8}/lib/metrics/src/main.js +0 -0
  530. /package/framework/{v0.6.7 → v0.6.8}/lib/model.js +0 -0
  531. /package/framework/{v0.6.7 → v0.6.8}/lib/net-locality/package.json +0 -0
  532. /package/framework/{v0.6.7 → v0.6.8}/lib/net-locality/src/main.js +0 -0
  533. /package/framework/{v0.6.7 → v0.6.8}/lib/nunjucks-filters/README.md +0 -0
  534. /package/framework/{v0.6.7 → v0.6.8}/lib/nunjucks-filters/package.json +0 -0
  535. /package/framework/{v0.6.7 → v0.6.8}/lib/nunjucks-filters/src/main.js +0 -0
  536. /package/framework/{v0.6.7 → v0.6.8}/lib/nunjucks-resolver/package.json +0 -0
  537. /package/framework/{v0.6.7 → v0.6.8}/lib/nunjucks-resolver/src/main.js +0 -0
  538. /package/framework/{v0.6.7 → v0.6.8}/lib/proc.js +0 -0
  539. /package/framework/{v0.6.7 → v0.6.8}/lib/release-watch/package.json +0 -0
  540. /package/framework/{v0.6.7 → v0.6.8}/lib/release-watch/src/main.js +0 -0
  541. /package/framework/{v0.6.7 → v0.6.8}/lib/render-cache/package.json +0 -0
  542. /package/framework/{v0.6.7 → v0.6.8}/lib/render-cache/src/main.js +0 -0
  543. /package/framework/{v0.6.7 → v0.6.8}/lib/render-cache-store.js +0 -0
  544. /package/framework/{v0.6.7 → v0.6.8}/lib/routing/README.md +0 -0
  545. /package/framework/{v0.6.7 → v0.6.8}/lib/routing/build.json +0 -0
  546. /package/framework/{v0.6.7 → v0.6.8}/lib/routing/package.json +0 -0
  547. /package/framework/{v0.6.7 → v0.6.8}/lib/routing/src/main.js +0 -0
  548. /package/framework/{v0.6.7 → v0.6.8}/lib/routing/src/radix.js +0 -0
  549. /package/framework/{v0.6.7 → v0.6.8}/lib/routing-introspect/package.json +0 -0
  550. /package/framework/{v0.6.7 → v0.6.8}/lib/routing-introspect/src/main.js +0 -0
  551. /package/framework/{v0.6.7 → v0.6.8}/lib/secrets/package.json +0 -0
  552. /package/framework/{v0.6.7 → v0.6.8}/lib/secrets/src/backends/env.js +0 -0
  553. /package/framework/{v0.6.7 → v0.6.8}/lib/secrets/src/backends/file.js +0 -0
  554. /package/framework/{v0.6.7 → v0.6.8}/lib/secrets/src/env-file.js +0 -0
  555. /package/framework/{v0.6.7 → v0.6.8}/lib/secrets/src/main.js +0 -0
  556. /package/framework/{v0.6.7 → v0.6.8}/lib/session-store.js +0 -0
  557. /package/framework/{v0.6.7 → v0.6.8}/lib/shell.js +0 -0
  558. /package/framework/{v0.6.7 → v0.6.8}/lib/sqlite-driver.js +0 -0
  559. /package/framework/{v0.6.7 → v0.6.8}/lib/state.js +0 -0
  560. /package/framework/{v0.6.7 → v0.6.8}/lib/storage/package.json +0 -0
  561. /package/framework/{v0.6.7 → v0.6.8}/lib/swig-filters/README.md +0 -0
  562. /package/framework/{v0.6.7 → v0.6.8}/lib/swig-filters/package.json +0 -0
  563. /package/framework/{v0.6.7 → v0.6.8}/lib/swig-filters/src/main.js +0 -0
  564. /package/framework/{v0.6.7 → v0.6.8}/lib/swig-resolver/package.json +0 -0
  565. /package/framework/{v0.6.7 → v0.6.8}/lib/swig-resolver/src/main.js +0 -0
  566. /package/framework/{v0.6.7 → v0.6.8}/lib/template-loaders/package.json +0 -0
  567. /package/framework/{v0.6.7 → v0.6.8}/lib/template-loaders/src/loaders/http.js +0 -0
  568. /package/framework/{v0.6.7 → v0.6.8}/lib/template-loaders/src/loaders/memory.js +0 -0
  569. /package/framework/{v0.6.7 → v0.6.8}/lib/template-loaders/src/main.js +0 -0
  570. /package/framework/{v0.6.7 → v0.6.8}/lib/url/README.md +0 -0
  571. /package/framework/{v0.6.7 → v0.6.8}/lib/url/index.js +0 -0
  572. /package/framework/{v0.6.7 → v0.6.8}/lib/url/routing.json +0 -0
  573. /package/framework/{v0.6.7 → v0.6.8}/lib/uuid/package.json +0 -0
  574. /package/framework/{v0.6.7 → v0.6.8}/lib/uuid/src/main.js +0 -0
  575. /package/framework/{v0.6.7 → v0.6.8}/lib/validator.js +0 -0
  576. /package/framework/{v0.6.7 → v0.6.8}/lib/watcher/package.json +0 -0
  577. /package/framework/{v0.6.7 → v0.6.8}/lib/watcher/src/main.js +0 -0
  578. /package/framework/{v0.6.7 → v0.6.8}/lib/ws-framing/package.json +0 -0
  579. /package/framework/{v0.6.7 → v0.6.8}/lib/ws-framing/src/main.js +0 -0
  580. /package/framework/{v0.6.7 → v0.6.8}/lib/ws-query/package.json +0 -0
  581. /package/framework/{v0.6.7 → v0.6.8}/lib/ws-query/src/main.js +0 -0
  582. /package/framework/{v0.6.7 → v0.6.8}/lib/ws-session/package.json +0 -0
  583. /package/framework/{v0.6.7 → v0.6.8}/lib/ws-session/src/main.js +0 -0
@@ -0,0 +1,1074 @@
1
+ /*
2
+ * This file is part of the gina package.
3
+ * Copyright (c) 2009-2026 Rhinostone <contact@gina.io>
4
+ *
5
+ * For the full copyright and license information, please view the LICENSE
6
+ * file that was distributed with this source code.
7
+ */
8
+ 'use strict';
9
+
10
+ /**
11
+ * @module gina/core/connectors/couchbase/storage-store
12
+ *
13
+ * Couchbase-backed `StorageMetaStore` for the object-storage layer
14
+ * (`lib/storage`) — the FIRST connector store of the #STO1 family, and the
15
+ * supported answer to the embedded backend's documented
16
+ * single-process-per-driver-root boundary. Backed by the consumer project's
17
+ * own `couchbase` driver (SDK major 3 or 4), resolved at construction — the
18
+ * framework keeps zero hard dependency on it.
19
+ *
20
+ * What it buys over the embedded SQLite store: the metadata row lives on a
21
+ * cluster every pod reaches, so several bundles (or replicas) can share ONE
22
+ * driver root. That is not a performance nicety — SQLite's locking is a
23
+ * known-broken story on a shared network filesystem, so a shared root is
24
+ * exactly what the embedded store refuses to support.
25
+ *
26
+ * **Per-key atomicity comes from Couchbase's own CAS**, which the refcount
27
+ * verbs need (`acquireRef` is what makes two concurrent identical `put()`s
28
+ * yield one blob and two references instead of a lost update). Every
29
+ * read-modify-write verb is a `get` → `mutateIn(..., {cas})` loop: the
30
+ * sub-document mutation applies all-or-none and only if the document has not
31
+ * changed since the read, so a lost update is impossible and a concurrent
32
+ * writer costs a bounded retry. CAS-guarded writes execute against the ACTIVE
33
+ * vBucket only (replicas serve reads, never writes), so the loop stays correct
34
+ * across a failover — each retry re-reads whatever node is active now.
35
+ *
36
+ * **Multi-process sweep coordination is the store's atomic claim, by design.**
37
+ * `removeIfZero` is a CAS-guarded `remove`: when several processes sweep the
38
+ * same root concurrently, exactly one claim per blob succeeds and every other
39
+ * one reads `CasMismatchError` / `DocumentNotFoundError` and skips — so the
40
+ * `local-cas` sweep protocol (claim the row FIRST, unlink second) is safe
41
+ * without any election layer, and adding one would close no gap while making
42
+ * `storage:gc` report `collected: 0` on whichever replica did not hold the
43
+ * lease. The residual the seam documents is unchanged and is NOT a
44
+ * sweeper-vs-sweeper race: it is put-vs-sweep (a fresh publish racing the
45
+ * unlink), mitigated by the grace window, the put-side heal and
46
+ * `storage:verify`.
47
+ *
48
+ * **Durability, stated rather than implied.** By default mutations use the
49
+ * SDK's own default level (in-memory on the active node), which is the same
50
+ * honesty class as the embedded store's SQLite WAL at `synchronous=NORMAL` —
51
+ * a crash can lose the most recent acknowledged write. Couchbase failover can
52
+ * likewise lose durably-written data. Consequences here are asymmetric and
53
+ * worth knowing: a lost `acquireRef` undercounts (a blob may reach zero early
54
+ * — gated by the grace window, adjudicated by the claim, visible to
55
+ * `storage:verify`), while a lost `releaseRef` overcounts and that blob is
56
+ * never collected. Set `durability` on the connectors.json entry when the
57
+ * content justifies the latency.
58
+ *
59
+ * Data layout — ONE JSON document per metadata row:
60
+ *
61
+ * <prefix><driver>:<key> the row. `d` (driver name) and `k` (logical key)
62
+ * are the sargable discriminators every query
63
+ * filters on; the contract fields ride beside them
64
+ * (`originalName`, `contentType`, `size`,
65
+ * `createdAt`), with `data` present only for
66
+ * size-tiered inline objects and `refs`/`zeroAt`
67
+ * present only on refcounted (cas) rows.
68
+ *
69
+ * The payload rides as a **base64 STRING inside the JSON document**, not as a
70
+ * binary document body: Couchbase cannot parse, index or query a binary value
71
+ * (it is retrievable by key alone), which would make `listZeroRefs` / `stats`
72
+ * structurally impossible — and the refcount and the payload must sit under
73
+ * ONE CAS for the verbs above to be atomic. The cost is base64's +33%: with
74
+ * the shipped 64KB tiering threshold a row is ~85KB, far below Couchbase's
75
+ * 20MB document ceiling, but an `inlineThreshold` above ~14MB would overflow
76
+ * it and the SDK will refuse the write.
77
+ *
78
+ * Config keys follow the couchbase connector's OWN conventions (the §11 rule —
79
+ * mirrors `connector.v4.js` / the session store): `protocol` + `host` +
80
+ * `username` + `password` + `database` (the BUCKET name — the same field the
81
+ * model layer's entity scan reads), plus `scope` / `collection` (both
82
+ * `_default`), `prefix` and the optional `durability`.
83
+ *
84
+ * Constructed by the `lib/storage-store` dispatcher at boot; not meant to be
85
+ * instantiated from application code.
86
+ *
87
+ * @example
88
+ * // connectors.json
89
+ * // { "assetsMeta": { "connector": "couchbase", "protocol": "couchbase://",
90
+ * // "host": "db1.internal", "username": "gina",
91
+ * // "password": "${secret:CB_PASSWORD}",
92
+ * // "database": "gina_storage" } }
93
+ * // settings.json
94
+ * // { "storage": { "drivers": { "assets": {
95
+ * // "adapter": "local", "strategy": "cas",
96
+ * // "root": "/var/data/assets", "store": "assetsMeta" } } } }
97
+ */
98
+
99
+ /**
100
+ * No-op callback used when a caller omits one.
101
+ * @inner
102
+ * @returns {void}
103
+ */
104
+ function noop() {}
105
+
106
+ /**
107
+ * Wrap a callback so it can fire at most once.
108
+ *
109
+ * Every verb here runs a promise chain nested inside another (the connection
110
+ * gate, then a CAS retry loop), so a callback that THROWS would reject the
111
+ * enclosing chain and reach a second, outer handler — delivering the caller's
112
+ * own exception back to them as a store error. The guard makes the first
113
+ * delivery the only one; the exception then surfaces as an unhandled
114
+ * rejection, where it belongs, instead of being laundered into `err`.
115
+ *
116
+ * @inner
117
+ * @param {function} fn - The callback to guard.
118
+ * @returns {function} The guarded callback.
119
+ */
120
+ function once(fn) {
121
+ if (typeof fn !== 'function') { return noop; }
122
+ var called = false;
123
+ return function() {
124
+ if (called) { return; }
125
+ called = true;
126
+ return fn.apply(null, arguments);
127
+ };
128
+ }
129
+
130
+ /**
131
+ * Secondary indexes this store needs, and the fields they cover. Created at
132
+ * construction when missing (see the bootstrap below); an operator whose
133
+ * cluster credentials cannot create indexes gets the exact DDL in a log line
134
+ * instead.
135
+ *
136
+ * `gina_storage_refs` serves `listZeroRefs` (the GC sweep's listing) and
137
+ * `gina_storage_keys` serves `listKeys` / `stats` (the `storage:verify` walk
138
+ * and the operator surface). Both lead with `d`, which every query filters on,
139
+ * so one collection can host several drivers without cross-scanning.
140
+ *
141
+ * @inner
142
+ * @constant
143
+ * @type {Array<{name: string, fields: string}>}
144
+ */
145
+ var INDEXES = [
146
+ { name: 'gina_storage_refs', fields: '(d, refs, zeroAt)' },
147
+ { name: 'gina_storage_keys', fields: '(d, k)' }
148
+ ];
149
+
150
+ /**
151
+ * Ceiling on how many times a CAS read-modify-write verb re-reads and retries
152
+ * before giving up. A BOUND, not a config knob (the `SWEEP_BATCH` precedent):
153
+ * it caps the work one contended key can cost, and exhaustion is reported
154
+ * through the callback as an ordinary error, never silently swallowed.
155
+ *
156
+ * @inner
157
+ * @constant
158
+ * @type {number}
159
+ */
160
+ var MAX_CAS_ATTEMPTS = 10;
161
+
162
+ /**
163
+ * Backoff schedule between CAS attempts, in ms — jittered at use so several
164
+ * contending processes do not re-collide in lockstep. The last value repeats
165
+ * once the schedule is exhausted.
166
+ *
167
+ * @inner
168
+ * @constant
169
+ * @type {number[]}
170
+ */
171
+ var CAS_BACKOFF_MS = [0, 5, 10, 20, 40];
172
+
173
+ /**
174
+ * Couchbase's hard ceiling on a document KEY, in bytes. The composed docId
175
+ * (`<prefix><driver>:<key>`) is checked against it per call: today's key
176
+ * grammars peak around half of it, so tripping this means a caller minted an
177
+ * unusually long key — and a truncating store would silently alias two
178
+ * objects onto one row.
179
+ *
180
+ * @inner
181
+ * @constant
182
+ * @type {number}
183
+ */
184
+ var MAX_DOC_ID_BYTES = 250;
185
+
186
+ /**
187
+ * Driver names that may safely compose a document-id namespace. A `:` would
188
+ * let one driver's name alias another's namespace boundary, so the character
189
+ * class is deliberately narrower than the file-system key guard's.
190
+ *
191
+ * @inner
192
+ * @constant
193
+ * @type {RegExp}
194
+ */
195
+ var DRIVER_NAME_RE = /^[A-Za-z0-9_.-]+$/;
196
+
197
+ /**
198
+ * Couchbase identifier grammar, for the three names that MUST be interpolated
199
+ * into statements rather than bound as parameters (a keyspace is an
200
+ * identifier, and N1QL has no placeholder for one). Anything outside this
201
+ * class is refused at construction — that refusal is what keeps the
202
+ * interpolation safe.
203
+ *
204
+ * @inner
205
+ * @constant
206
+ * @type {RegExp}
207
+ */
208
+ var IDENTIFIER_RE = /^[A-Za-z0-9_%\-]+$/;
209
+
210
+ /**
211
+ * Accepted `durability` values → the SDK's `DurabilityLevel` member name.
212
+ * BOTH spellings are accepted for the middle level because the server
213
+ * documentation and the Node SDK disagree: the docs call it
214
+ * `majorityAndPersistToActive`, the SDK enum member is
215
+ * `MajorityAndPersistOnMaster`. Accepting only one of them would silently
216
+ * drop a correctly-configured durability level.
217
+ *
218
+ * @inner
219
+ * @constant
220
+ * @type {Object.<string, string>}
221
+ */
222
+ var DURABILITY_LEVELS = {
223
+ none : 'None',
224
+ majority : 'Majority',
225
+ majorityandpersisttoactive : 'MajorityAndPersistOnMaster',
226
+ majorityandpersistonmaster : 'MajorityAndPersistOnMaster',
227
+ persisttomajority : 'PersistToMajority'
228
+ };
229
+
230
+ /**
231
+ * Build a Couchbase-backed metadata store implementing the
232
+ * {@link StorageMetaStore} seam — the four base verbs (`set` / `get` /
233
+ * `remove` / `close`), the four refcount verbs a `cas` driver requires
234
+ * (`acquireRef` / `releaseRef` / `listZeroRefs` / `removeIfZero`) and both
235
+ * optional operator verbs (`stats` / `listKeys`).
236
+ *
237
+ * The SDK is promise-based, so callbacks fire asynchronously — which the seam
238
+ * explicitly allows (the embedded store's synchronous timing is an
239
+ * implementation detail of `node:sqlite`, never part of the contract).
240
+ *
241
+ * @param {object} connConf - Resolved `connectors.json` entry for this store.
242
+ * @param {string} [connConf.protocol] - Connection scheme (default `'couchbase://'`).
243
+ * @param {string} [connConf.host] - Host or comma-separated hosts (default 127.0.0.1).
244
+ * @param {string} [connConf.username] - Cluster username.
245
+ * @param {string} [connConf.password] - Cluster password.
246
+ * @param {string} connConf.database - Bucket NAME (required — the couchbase connector's
247
+ * own convention; the model layer reads the same field).
248
+ * @param {string} [connConf.scope] - Scope name (default `'_default'`).
249
+ * @param {string} [connConf.collection] - Collection name (default `'_default'`).
250
+ * @param {string} [connConf.prefix] - Document-id prefix (default `'stor:'`).
251
+ * @param {string} [connConf.durability] - Durability level applied to every mutation:
252
+ * `majority` | `majorityAndPersistToActive` |
253
+ * `persistToMajority` (or `none`). Omitted, the SDK
254
+ * default applies — see the module header.
255
+ * @param {string} bundle - Bundle name — used in log lines.
256
+ * @param {string} driverName - Storage driver this store backs. It NAMESPACES every
257
+ * document id and scopes every query, so several
258
+ * drivers may share one connectors.json entry without
259
+ * colliding keys, stamps or refcounts.
260
+ * @param {object} [injected] - Test-only dependency injection (the entity-layer
261
+ * `injected` precedent): `{ driver }` replaces the
262
+ * project-resolved couchbase module.
263
+ * @returns {StorageMetaStore} - A ready store (plus `close()`).
264
+ * @throws {Error} - When the couchbase driver is not installed, the SDK
265
+ * major is unsupported, `database` is missing, or a
266
+ * driver/keyspace name is unusable. `gna.js` treats a
267
+ * throw as a boot fatal — an explicitly configured
268
+ * store must build or refuse, never degrade to the
269
+ * embedded backend.
270
+ *
271
+ * @example
272
+ * // wired automatically at boot by gna.js via lib/storage-store
273
+ * var store = require('.../couchbase/lib/storage-store')(connConf, 'app', 'assets');
274
+ */
275
+ module.exports = function CouchbaseStorageStore(connConf, bundle, driverName, injected) {
276
+ connConf = connConf || {};
277
+
278
+ if ( typeof driverName !== 'string' || !DRIVER_NAME_RE.test(driverName) ) {
279
+ throw new Error('[CouchbaseStorageStore] a storage driver name is required and must match '
280
+ + DRIVER_NAME_RE + ' (got: ' + JSON.stringify(driverName) + ') — it namespaces every '
281
+ + 'document id, so a `:` in it would alias another driver\'s namespace');
282
+ }
283
+
284
+ // Resolve the couchbase driver from the project's node_modules (the
285
+ // connector's own precedent — core/connectors/couchbase/index.js:8-9 —
286
+ // and the mongodb job-store's). The injected branch is test-only; the
287
+ // default branch is the only place the injected `_` / `getPath` globals
288
+ // are read, so tests stay standalone.
289
+ var couchbase;
290
+ if (injected && injected.driver) {
291
+ couchbase = injected.driver;
292
+ } else {
293
+ try {
294
+ var driverPath = _(getPath('project') + '/node_modules/couchbase', true);
295
+ couchbase = require(driverPath);
296
+ } catch (e) {
297
+ throw new Error(
298
+ '[CouchbaseStorageStore] couchbase is not installed. '
299
+ + 'Run `npm install couchbase` in your project (SDK major 3 or 4).\n'
300
+ + e.message
301
+ );
302
+ }
303
+ }
304
+
305
+ if ( typeof couchbase.connect !== 'function' ) {
306
+ // #CN8 parity: SDK v2 exposed cluster.openBucket() and no connect().
307
+ throw new Error('[CouchbaseStorageStore] the installed couchbase driver exposes no `connect()` — '
308
+ + 'supported SDK majors are 3 and 4. Upgrade the couchbase dependency in your project '
309
+ + 'package.json: npm install couchbase@^4 (or ^3).');
310
+ }
311
+
312
+ var bucketName = connConf.database;
313
+ if (!bucketName) {
314
+ throw new Error('[CouchbaseStorageStore] missing required `database` field (the bucket name) in the connectors.json entry');
315
+ }
316
+
317
+ var scopeName = connConf.scope || '_default';
318
+ var collectionName = connConf.collection || '_default';
319
+ var prefix = ( typeof connConf.prefix === 'string' && connConf.prefix.length > 0 ) ? connConf.prefix : 'stor:';
320
+
321
+ // The keyspace is an IDENTIFIER, and N1QL has no placeholder for one, so
322
+ // these three names are interpolated into every statement. Validating them
323
+ // here — once, at construction — is what makes that interpolation safe;
324
+ // every VALUE below is a positional parameter.
325
+ [['database', bucketName], ['scope', scopeName], ['collection', collectionName]].forEach(function(pair) {
326
+ if ( typeof pair[1] !== 'string' || !IDENTIFIER_RE.test(pair[1]) ) {
327
+ throw new Error('[CouchbaseStorageStore] `' + pair[0] + '` must match ' + IDENTIFIER_RE
328
+ + ' (got: ' + JSON.stringify(pair[1]) + ') — it is interpolated into N1QL statements as an identifier');
329
+ }
330
+ });
331
+
332
+ /**
333
+ * Backtick-quoted keyspace, e.g. `` `gina_storage`.`_default`.`_default` ``.
334
+ * @inner
335
+ * @type {string}
336
+ */
337
+ var keyspace = '`' + bucketName + '`.`' + scopeName + '`.`' + collectionName + '`';
338
+
339
+ /**
340
+ * Resolved SDK durability option, merged into every mutation. `null` when
341
+ * unconfigured — the SDK's own default then applies.
342
+ *
343
+ * @inner
344
+ * @type {?object}
345
+ */
346
+ var durabilityOpt = null;
347
+ if ( typeof connConf.durability === 'string' && connConf.durability.length > 0 ) {
348
+ var member = DURABILITY_LEVELS[connConf.durability.toLowerCase()];
349
+ if (!member) {
350
+ throw new Error('[CouchbaseStorageStore] unknown `durability` ' + JSON.stringify(connConf.durability)
351
+ + ' — expected one of: majority, majorityAndPersistToActive, persistToMajority, none');
352
+ }
353
+ if ( !couchbase.DurabilityLevel || typeof couchbase.DurabilityLevel[member] === 'undefined' ) {
354
+ throw new Error('[CouchbaseStorageStore] `durability` ' + JSON.stringify(connConf.durability)
355
+ + ' is not available on the installed couchbase SDK (no DurabilityLevel.' + member + ')');
356
+ }
357
+ durabilityOpt = { durabilityLevel: couchbase.DurabilityLevel[member] };
358
+ }
359
+
360
+ /**
361
+ * Merge the configured durability into a per-operation options bag.
362
+ *
363
+ * @inner
364
+ * @param {object} [opt] - Base options (e.g. `{cas}`).
365
+ * @returns {object} The options to hand the SDK.
366
+ */
367
+ var withDurability = function(opt) {
368
+ opt = opt || {};
369
+ if (durabilityOpt) { opt.durabilityLevel = durabilityOpt.durabilityLevel; }
370
+ return opt;
371
+ };
372
+
373
+ /**
374
+ * Whether `err` is the named Couchbase error class. Checked by
375
+ * constructor identity first, then by name — a driver that surfaces the
376
+ * class only by name (or a test double) still classifies correctly, and
377
+ * misclassifying here would turn a resurrection signal into a hard
378
+ * failure.
379
+ *
380
+ * @inner
381
+ * @param {*} err - Any thrown/rejected value.
382
+ * @param {string} className - e.g. `'CasMismatchError'`.
383
+ * @returns {boolean}
384
+ */
385
+ var isCbError = function(err, className) {
386
+ if (!err) { return false; }
387
+ var Ctor = couchbase[className];
388
+ if ( typeof Ctor === 'function' && err instanceof Ctor ) { return true; }
389
+ if ( err.name === className ) { return true; }
390
+ if ( err.constructor && err.constructor.name === className ) { return true; }
391
+ return false;
392
+ };
393
+
394
+ /**
395
+ * Compose the document id for a logical key, refusing one that would
396
+ * exceed Couchbase's key ceiling.
397
+ *
398
+ * @inner
399
+ * @param {string} key - The logical storage key.
400
+ * @returns {{id: ?string, error: ?Error}}
401
+ */
402
+ var docIdFor = function(key) {
403
+ var id = prefix + driverName + ':' + key;
404
+ if ( Buffer.byteLength(id, 'utf8') > MAX_DOC_ID_BYTES ) {
405
+ return { id: null, error: new Error('[CouchbaseStorageStore] the composed document id for key `' + key
406
+ + '` is ' + Buffer.byteLength(id, 'utf8') + ' bytes, over Couchbase\'s ' + MAX_DOC_ID_BYTES
407
+ + '-byte key limit (prefix `' + prefix + '` + driver `' + driverName + '`)') };
408
+ }
409
+ return { id: id, error: null };
410
+ };
411
+
412
+ /**
413
+ * Build the stored document for `key` + `meta`.
414
+ *
415
+ * Absent optional fields are OMITTED rather than written as `null`, which
416
+ * is what lets `get()` rebuild a row's exact contract shape: a
417
+ * non-refcounted row must come back without `refs`/`zeroAt`, and a
418
+ * file-backed row without `data`. A refcounted row always carries BOTH
419
+ * `refs` and `zeroAt` (the latter valued `null` while `refs > 0`) —
420
+ * mirroring the embedded store, whose NULL column reads back as `null`.
421
+ *
422
+ * @inner
423
+ * @param {string} key - Logical storage key.
424
+ * @param {StorageMeta} meta - Caller metadata (may carry `data`).
425
+ * @param {boolean} refcounted - Stamp `refs: 1` / `zeroAt: null` (the acquireRef create).
426
+ * @returns {object} The document to store.
427
+ */
428
+ var buildDoc = function(key, meta, refcounted) {
429
+ meta = meta || {};
430
+ var doc = {
431
+ d : driverName,
432
+ k : key,
433
+ originalName : ( typeof meta.originalName === 'string' ) ? meta.originalName : null,
434
+ contentType : ( typeof meta.contentType === 'string' ) ? meta.contentType : null,
435
+ size : ( typeof meta.size === 'number' ) ? meta.size : null,
436
+ createdAt : ( typeof meta.createdAt === 'number' ) ? meta.createdAt : Date.now()
437
+ };
438
+ // Binary safety: a Buffer IS a Uint8Array and base64-encodes exactly;
439
+ // anything else (a string above all — utf8 coercion would corrupt a
440
+ // binary payload) is refused rather than encoded, matching the
441
+ // embedded store's refusal-to-NULL.
442
+ if ( meta.data instanceof Uint8Array ) {
443
+ doc.data = Buffer.isBuffer(meta.data)
444
+ ? meta.data.toString('base64')
445
+ : Buffer.from(meta.data).toString('base64');
446
+ }
447
+ if (refcounted) {
448
+ doc.refs = 1;
449
+ doc.zeroAt = null;
450
+ }
451
+ return doc;
452
+ };
453
+
454
+ /**
455
+ * Rebuild the contract-shaped metadata object from a stored document.
456
+ *
457
+ * @inner
458
+ * @param {object} doc - The stored document.
459
+ * @param {boolean} includePayload - Attach `data` when the row carries one.
460
+ * @returns {StorageMeta}
461
+ */
462
+ var metaFromDoc = function(doc, includePayload) {
463
+ var meta = {
464
+ originalName : ( typeof doc.originalName === 'string' ) ? doc.originalName : null,
465
+ contentType : ( typeof doc.contentType === 'string' ) ? doc.contentType : null,
466
+ size : ( typeof doc.size === 'number' ) ? doc.size : null,
467
+ createdAt : ( typeof doc.createdAt === 'number' ) ? doc.createdAt : null
468
+ };
469
+ // Present only for inline objects, so a file-backed row keeps its
470
+ // exact pre-tiering shape. A zero-length payload is a real empty
471
+ // object, distinct from an absent one — base64 '' decodes to it.
472
+ if ( includePayload && typeof doc.data === 'string' ) {
473
+ meta.data = Buffer.from(doc.data, 'base64');
474
+ }
475
+ // Present only for refcounted rows — the same pattern as `data`.
476
+ if ( typeof doc.refs === 'number' ) {
477
+ meta.refs = doc.refs;
478
+ meta.zeroAt = ( typeof doc.zeroAt === 'number' ) ? doc.zeroAt : null;
479
+ }
480
+ return meta;
481
+ };
482
+
483
+ /**
484
+ * Pause between CAS attempts, jittered so contending processes do not
485
+ * re-collide in lockstep.
486
+ *
487
+ * @inner
488
+ * @param {number} attempt - Zero-based attempt index.
489
+ * @param {function} next - Called after the pause.
490
+ * @returns {void}
491
+ */
492
+ var backoff = function(attempt, next) {
493
+ var base = CAS_BACKOFF_MS[Math.min(attempt, CAS_BACKOFF_MS.length - 1)];
494
+ if (!base) { return setImmediate(next); }
495
+ setTimeout(next, base + Math.floor(Math.random() * base));
496
+ };
497
+
498
+ /**
499
+ * The error a CAS loop reports once {@link MAX_CAS_ATTEMPTS} is spent.
500
+ * Carries a code so a caller can distinguish sustained contention from a
501
+ * cluster fault.
502
+ *
503
+ * @inner
504
+ * @param {string} verb - Verb name, for the message.
505
+ * @param {string} key - Logical key.
506
+ * @returns {Error}
507
+ */
508
+ var contentionError = function(verb, key) {
509
+ var err = new Error('[CouchbaseStorageStore] ' + verb + '(`' + key + '`) gave up after '
510
+ + MAX_CAS_ATTEMPTS + ' CAS attempts — the row is under sustained concurrent modification');
511
+ err.code = 'GINA_STORAGE_CAS_CONTENTION';
512
+ return err;
513
+ };
514
+
515
+ // ─── Connection ──────────────────────────────────────────────────────────
516
+
517
+ var connStr = ( connConf.protocol || 'couchbase://' ) + ( connConf.host || '127.0.0.1' );
518
+ var cluster = null;
519
+
520
+ /**
521
+ * Resolves to the open collection once the cluster is up. Every verb
522
+ * chains on it, so operations issued before the connection completes are
523
+ * queued rather than lost — and a connection failure surfaces through
524
+ * each verb's own callback instead of as an unhandled rejection.
525
+ *
526
+ * @inner
527
+ * @type {Promise<object>}
528
+ */
529
+ var ready = Promise.resolve()
530
+ .then(function() {
531
+ return couchbase.connect(connStr, {
532
+ username : connConf.username,
533
+ password : connConf.password
534
+ });
535
+ })
536
+ .then(function(c) {
537
+ cluster = c;
538
+ return c.bucket(bucketName).scope(scopeName).collection(collectionName);
539
+ });
540
+
541
+ ready.catch(function(err) {
542
+ console.error('[CouchbaseStorageStore] connection to `' + connStr + '` failed (bundle: '
543
+ + bundle + ', driver: ' + driverName + '): ' + ((err && err.message) || err));
544
+ });
545
+
546
+ /**
547
+ * Run `fn` against the open collection, funnelling any connection failure
548
+ * into the caller's callback.
549
+ *
550
+ * @inner
551
+ * @param {function} fn - `fn(collection)`.
552
+ * @param {function} cb - The verb's callback; receives a connection error.
553
+ * @returns {void}
554
+ */
555
+ var withCollection = function(fn, cb) {
556
+ ready.then(fn).catch(function(err) { cb(err); });
557
+ };
558
+
559
+ /**
560
+ * Run a N1QL statement. `NotBounded` scan consistency is deliberate and
561
+ * safe here: index staleness can only make a listing MISS a row or offer
562
+ * a stale candidate, and every destructive step that follows re-adjudicates
563
+ * against the document itself through CAS — the listing is a trigger, the
564
+ * KV operation is the verdict.
565
+ *
566
+ * @inner
567
+ * @param {string} statement - The N1QL statement.
568
+ * @param {Array} params - Positional parameters (`$1..$N`).
569
+ * @param {function} cb - `cb(err, rows)`.
570
+ * @returns {void}
571
+ */
572
+ var runQuery = function(statement, params, cb) {
573
+ ready.then(function() {
574
+ var opt = {
575
+ parameters : params,
576
+ // never re-plan a statement we compose ourselves
577
+ adhoc : false
578
+ };
579
+ if ( couchbase.QueryScanConsistency && typeof couchbase.QueryScanConsistency.NotBounded !== 'undefined' ) {
580
+ opt.scanConsistency = couchbase.QueryScanConsistency.NotBounded;
581
+ }
582
+ return cluster.query(statement, opt);
583
+ }).then(function(res) {
584
+ cb(null, ( res && res.rows ) || []);
585
+ }).catch(function(err) {
586
+ cb(err);
587
+ });
588
+ };
589
+
590
+ /**
591
+ * Validate a caller-supplied row limit. It is INTERPOLATED into the
592
+ * statement rather than bound, which keeps each statement a stable string
593
+ * for the query plan cache — so it must be a plain positive integer, and
594
+ * anything else falls back to the caller's documented default rather than
595
+ * reaching the server.
596
+ *
597
+ * @inner
598
+ * @param {*} limit - Caller value.
599
+ * @param {number} dflt - Fallback.
600
+ * @returns {number}
601
+ */
602
+ var safeLimit = function(limit, dflt) {
603
+ return ( Number.isSafeInteger(limit) && limit > 0 ) ? limit : dflt;
604
+ };
605
+
606
+ // ─── Index bootstrap ─────────────────────────────────────────────────────
607
+
608
+ /**
609
+ * Ensure the two secondary indexes exist — eager and fire-and-forget (the
610
+ * mongodb job-store precedent): no operation waits on it.
611
+ *
612
+ * Existence is probed through `system:indexes` rather than relying on
613
+ * `CREATE INDEX IF NOT EXISTS`, whose availability depends on the server
614
+ * version this store has no way to require. The probe covers both
615
+ * keyspace shapes: on the default collection `keyspace_id` IS the bucket
616
+ * and `bucket_id` is missing; on a named collection the three ids are
617
+ * bucket / scope / collection.
618
+ *
619
+ * A failure here is NOT fatal — an operator whose credentials cannot
620
+ * create indexes is a normal deployment — but it is logged with the exact
621
+ * DDL to run by hand, because the consequence is not "slower queries": an
622
+ * unindexed query ERRORS, and the periodic sweep's bare call would
623
+ * swallow that error forever. Every query verb therefore logs its own
624
+ * failures too.
625
+ *
626
+ * @inner
627
+ * @returns {void}
628
+ */
629
+ var ensureIndexes = function() {
630
+ var names = INDEXES.map(function(i) { return '"' + i.name + '"'; }).join(', ');
631
+ var probe = 'SELECT name FROM system:indexes'
632
+ + ' WHERE name IN [' + names + ']'
633
+ + ' AND ( (bucket_id IS MISSING AND keyspace_id = $1)'
634
+ + ' OR (bucket_id = $1 AND scope_id = $2 AND keyspace_id = $3) )';
635
+
636
+ runQuery(probe, [bucketName, scopeName, collectionName], function(err, rows) {
637
+ if (err) {
638
+ return console.warn('[CouchbaseStorageStore] could not inspect system:indexes (bundle: ' + bundle
639
+ + ', driver: ' + driverName + '): ' + ((err && err.message) || err)
640
+ + ' — create these by hand if queries fail: ' + ddlLines().join(' ; '));
641
+ }
642
+ var have = {};
643
+ (rows || []).forEach(function(r) { if (r && r.name) { have[r.name] = true; } });
644
+ INDEXES.forEach(function(idx) {
645
+ if (have[idx.name]) { return; }
646
+ var ddl = 'CREATE INDEX `' + idx.name + '` ON ' + keyspace + idx.fields;
647
+ runQuery(ddl, [], function(createErr) {
648
+ if (createErr) {
649
+ // IndexExistsError is the benign race: a sibling
650
+ // process created it between the probe and here.
651
+ if ( isCbError(createErr, 'IndexExistsError') ) { return; }
652
+ console.warn('[CouchbaseStorageStore] could not create index `' + idx.name + '` (bundle: '
653
+ + bundle + ', driver: ' + driverName + '): ' + ((createErr && createErr.message) || createErr)
654
+ + ' — run it by hand: ' + ddl);
655
+ }
656
+ });
657
+ });
658
+ });
659
+ };
660
+
661
+ /**
662
+ * The DDL for every index this store needs — surfaced in log lines so an
663
+ * operator can create them by hand.
664
+ *
665
+ * @inner
666
+ * @returns {string[]}
667
+ */
668
+ var ddlLines = function() {
669
+ return INDEXES.map(function(idx) {
670
+ return 'CREATE INDEX `' + idx.name + '` ON ' + keyspace + idx.fields;
671
+ });
672
+ };
673
+
674
+ ensureIndexes();
675
+
676
+ // ─── Statements ──────────────────────────────────────────────────────────
677
+ //
678
+ // Composed once. Every VALUE is a positional parameter; only the keyspace
679
+ // (an identifier, which N1QL cannot bind) and the row limit are
680
+ // interpolated, both from validated input.
681
+
682
+ /**
683
+ * `refs IS VALUED` is the LOAD-BEARING guard, not decoration: a
684
+ * non-refcounted row carries no `refs` field at all, and this is what
685
+ * keeps such rows structurally invisible to the GC sweep — the same role
686
+ * the embedded store gets free from SQL's `NULL != 0`.
687
+ *
688
+ * @inner
689
+ * @param {number} limit
690
+ * @returns {string}
691
+ */
692
+ var zeroRefsStatement = function(limit) {
693
+ return 'SELECT k FROM ' + keyspace
694
+ + ' WHERE d = $1 AND refs IS VALUED AND refs = 0'
695
+ + ' AND zeroAt IS VALUED AND zeroAt <= $2'
696
+ + ' ORDER BY zeroAt LIMIT ' + limit;
697
+ };
698
+
699
+ /**
700
+ * Key-ordered pagination, reserved dot-keys excluded — ordering by the
701
+ * key is what keeps the cursor stable while the bundle keeps writing.
702
+ *
703
+ * @inner
704
+ * @param {number} limit
705
+ * @returns {string}
706
+ */
707
+ var keysStatement = function(limit) {
708
+ return 'SELECT k FROM ' + keyspace
709
+ + ' WHERE d = $1 AND k > $2 AND k NOT LIKE ".%"'
710
+ + ' ORDER BY k LIMIT ' + limit;
711
+ };
712
+
713
+ /**
714
+ * One aggregate pass for the operator surface. `IFMISSINGORNULL` is what
715
+ * makes an EMPTY driver report zeroes rather than nulls (SUM over no rows
716
+ * is NULL) — the embedded store's `COALESCE`.
717
+ *
718
+ * `inline` is BACKTICKED because it is a N1QL reserved word (#B356) — the
719
+ * server refuses the whole statement with `at: inline (reserved word)`, so
720
+ * `stats` was the one maintenance verb that could not parse against a real
721
+ * cluster. Escaping it changes nothing else: a quoted alias still yields
722
+ * the bare key `inline` in the result row, which `stats()` below reads.
723
+ * The other four aliases are NOT reserved (checked against Couchbase's
724
+ * reserved-word list, which is why they are left bare) and `§07` pins that
725
+ * none of them silently becomes one.
726
+ *
727
+ * @inner
728
+ * @type {string}
729
+ */
730
+ var statsStatement = 'SELECT COUNT(1) AS objects,'
731
+ + ' IFMISSINGORNULL(SUM(CASE WHEN refs IS VALUED THEN 1 ELSE 0 END), 0) AS refcounted,'
732
+ + ' IFMISSINGORNULL(SUM(CASE WHEN refs = 0 THEN 1 ELSE 0 END), 0) AS zeroRefPending,'
733
+ + ' IFMISSINGORNULL(SUM(CASE WHEN data IS VALUED THEN 1 ELSE 0 END), 0) AS `inline`,'
734
+ + ' IFMISSINGORNULL(SUM(size), 0) AS bytes'
735
+ + ' FROM ' + keyspace
736
+ + ' WHERE d = $1 AND k NOT LIKE ".%"';
737
+
738
+ return {
739
+
740
+ /**
741
+ * Upsert `meta` under `key` — REPLACE semantics, exactly like the
742
+ * embedded store's `INSERT OR REPLACE`.
743
+ *
744
+ * Never call this on a refcounted row: it would drop `refs`/`zeroAt`
745
+ * and reset the count. `acquireRef` owns those rows.
746
+ *
747
+ * @param {string} key
748
+ * @param {StorageMeta} meta
749
+ * @param {function} [fn] - `fn(err, meta)`.
750
+ * @returns {void}
751
+ */
752
+ set: function(key, meta, fn) {
753
+ fn = once(fn);
754
+ meta = meta || {};
755
+ var d = docIdFor(key);
756
+ if (d.error) { return fn(d.error); }
757
+ withCollection(function(coll) {
758
+ return coll.upsert(d.id, buildDoc(key, meta, false), withDurability())
759
+ .then(function() { fn(null, meta); });
760
+ }, fn);
761
+ },
762
+
763
+ /**
764
+ * Fetch metadata by `key`.
765
+ *
766
+ * @param {string} key
767
+ * @param {function} fn - `fn(err, meta|null)`; `null` when the key is unknown.
768
+ * @returns {void}
769
+ */
770
+ get: function(key, fn) {
771
+ fn = once(fn);
772
+ var d = docIdFor(key);
773
+ if (d.error) { return fn(d.error); }
774
+ withCollection(function(coll) {
775
+ return coll.get(d.id)
776
+ .then(function(res) { fn(null, metaFromDoc(res.content, true)); })
777
+ .catch(function(err) {
778
+ if ( isCbError(err, 'DocumentNotFoundError') ) { return fn(null, null); }
779
+ fn(err);
780
+ });
781
+ }, fn);
782
+ },
783
+
784
+ /**
785
+ * Delete metadata by `key`.
786
+ *
787
+ * @param {string} key
788
+ * @param {function} [fn] - `fn(err, existed)`.
789
+ * @returns {void}
790
+ */
791
+ remove: function(key, fn) {
792
+ fn = once(fn);
793
+ var d = docIdFor(key);
794
+ if (d.error) { return fn(d.error); }
795
+ withCollection(function(coll) {
796
+ return coll.remove(d.id, withDurability())
797
+ .then(function() { fn(null, true); })
798
+ .catch(function(err) {
799
+ if ( isCbError(err, 'DocumentNotFoundError') ) { return fn(null, false); }
800
+ fn(err);
801
+ });
802
+ }, fn);
803
+ },
804
+
805
+ /**
806
+ * Atomically take one reference on `key` — insert-or-increment.
807
+ *
808
+ * Missing row: inserted with `meta` and `refs` = 1 (`created: true`);
809
+ * a concurrent insert loses on `DocumentExistsError` and retries into
810
+ * the increment branch. Existing refcounted row: `refs` incremented
811
+ * and `zeroAt` cleared (a blob inside the GC grace window is
812
+ * resurrected), with the INCOMING meta ignored — first-write-wins.
813
+ *
814
+ * Atomicity is Couchbase's CAS: the read's CAS token guards the
815
+ * sub-document mutation, so an interleaved writer invalidates this
816
+ * attempt rather than silently overwriting it.
817
+ *
818
+ * A row that exists but carries NO `refs` is REFUSED loudly rather
819
+ * than adopted: it belongs to something else (a `sharded` row, or the
820
+ * `.driver` stamp), and quietly stamping a refcount onto it would
821
+ * corrupt that owner's data. The embedded store gets the same
822
+ * loudness from its PRIMARY KEY conflict.
823
+ *
824
+ * @param {string} key - The blob key.
825
+ * @param {StorageMeta} meta - Metadata for the CREATE case (may carry `data`).
826
+ * @param {function} [fn] - `fn(err, {created: boolean, refs: number, meta: StorageMeta})`.
827
+ * @returns {void}
828
+ */
829
+ acquireRef: function(key, meta, fn) {
830
+ fn = once(fn);
831
+ meta = meta || {};
832
+ var d = docIdFor(key);
833
+ if (d.error) { return fn(d.error); }
834
+
835
+ withCollection(function(coll) {
836
+ var attempt = function(n) {
837
+ if ( n >= MAX_CAS_ATTEMPTS ) { return fn(contentionError('acquireRef', key)); }
838
+
839
+ coll.get(d.id).then(function(res) {
840
+ var doc = res.content;
841
+ if ( typeof doc.refs !== 'number' ) {
842
+ return fn(new Error('[CouchbaseStorageStore] acquireRef(`' + key + '`) refuses to adopt an '
843
+ + 'existing non-refcounted row — it belongs to another strategy (or is the `.driver` '
844
+ + 'stamp), and taking a reference on it would corrupt its owner'));
845
+ }
846
+ var next = doc.refs + 1;
847
+ return coll.mutateIn(d.id, [
848
+ couchbase.MutateInSpec.upsert('refs', next),
849
+ couchbase.MutateInSpec.upsert('zeroAt', null)
850
+ ], withDurability({ cas: res.cas })).then(function() {
851
+ fn(null, {
852
+ created : false,
853
+ refs : next,
854
+ meta : {
855
+ originalName : ( typeof doc.originalName === 'string' ) ? doc.originalName : null,
856
+ contentType : ( typeof doc.contentType === 'string' ) ? doc.contentType : null,
857
+ size : ( typeof doc.size === 'number' ) ? doc.size : null,
858
+ createdAt : ( typeof doc.createdAt === 'number' ) ? doc.createdAt : null,
859
+ refs : next
860
+ }
861
+ });
862
+ }).catch(function(err) {
863
+ if ( isCbError(err, 'CasMismatchError') || isCbError(err, 'DocumentNotFoundError') ) {
864
+ return backoff(n, function() { attempt(n + 1); });
865
+ }
866
+ fn(err);
867
+ });
868
+ }).catch(function(getErr) {
869
+ if ( !isCbError(getErr, 'DocumentNotFoundError') ) { return fn(getErr); }
870
+ coll.insert(d.id, buildDoc(key, meta, true), withDurability())
871
+ .then(function() { fn(null, { created: true, refs: 1, meta: meta }); })
872
+ .catch(function(insErr) {
873
+ if ( isCbError(insErr, 'DocumentExistsError') ) {
874
+ return backoff(n, function() { attempt(n + 1); });
875
+ }
876
+ fn(insErr);
877
+ });
878
+ });
879
+ };
880
+ attempt(0);
881
+ }, fn);
882
+ },
883
+
884
+ /**
885
+ * Atomically drop one reference on `key`.
886
+ *
887
+ * Floors at 0 and stamps `zeroAt` at the 1 → 0 transition — the
888
+ * timestamp the GC grace window reads. Both fields move in ONE
889
+ * `mutateIn`, which applies all-or-none, so the invariant (`zeroAt`
890
+ * non-null exactly when `refs === 0`) can never be observed broken.
891
+ *
892
+ * A missing, non-refcounted, or already-zero row answers
893
+ * `{existed: false}`: the reference the caller wanted to drop was
894
+ * already gone, which is the outcome they asked for.
895
+ *
896
+ * @param {string} key - The blob key.
897
+ * @param {function} [fn] - `fn(err, {existed: boolean, refs: number})` — `refs` is the
898
+ * count AFTER the decrement.
899
+ * @returns {void}
900
+ */
901
+ releaseRef: function(key, fn) {
902
+ fn = once(fn);
903
+ var d = docIdFor(key);
904
+ if (d.error) { return fn(d.error); }
905
+
906
+ withCollection(function(coll) {
907
+ var attempt = function(n) {
908
+ if ( n >= MAX_CAS_ATTEMPTS ) { return fn(contentionError('releaseRef', key)); }
909
+
910
+ coll.get(d.id).then(function(res) {
911
+ var doc = res.content;
912
+ if ( typeof doc.refs !== 'number' || doc.refs < 1 ) {
913
+ return fn(null, { existed: false, refs: ( typeof doc.refs === 'number' ) ? doc.refs : 0 });
914
+ }
915
+ var next = doc.refs - 1;
916
+ return coll.mutateIn(d.id, [
917
+ couchbase.MutateInSpec.upsert('refs', next),
918
+ couchbase.MutateInSpec.upsert('zeroAt', ( next === 0 ) ? Date.now() : null)
919
+ ], withDurability({ cas: res.cas })).then(function() {
920
+ fn(null, { existed: true, refs: next });
921
+ }).catch(function(err) {
922
+ if ( isCbError(err, 'CasMismatchError') || isCbError(err, 'DocumentNotFoundError') ) {
923
+ return backoff(n, function() { attempt(n + 1); });
924
+ }
925
+ fn(err);
926
+ });
927
+ }).catch(function(getErr) {
928
+ if ( isCbError(getErr, 'DocumentNotFoundError') ) {
929
+ return fn(null, { existed: false, refs: 0 });
930
+ }
931
+ fn(getErr);
932
+ });
933
+ };
934
+ attempt(0);
935
+ }, fn);
936
+ },
937
+
938
+ /**
939
+ * Keys whose refcount has sat at 0 since before `olderThanMs` —
940
+ * oldest first, at most `limit`.
941
+ *
942
+ * Non-refcounted rows carry no `refs` field, which `refs IS VALUED`
943
+ * excludes, so they are structurally invisible here.
944
+ *
945
+ * @param {number} olderThanMs - Epoch ms cutoff (typically now − grace).
946
+ * @param {number} limit - Batch cap.
947
+ * @param {function} fn - `fn(err, string[])`.
948
+ * @returns {void}
949
+ */
950
+ listZeroRefs: function(olderThanMs, limit, fn) {
951
+ fn = once(fn);
952
+ runQuery(zeroRefsStatement(safeLimit(limit, 100)), [driverName, olderThanMs], function(err, rows) {
953
+ if (err) {
954
+ // The sweep's own call passes no callback, so an error
955
+ // that only travelled through `fn` would vanish and GC
956
+ // would appear to work forever while collecting nothing.
957
+ console.error('[CouchbaseStorageStore] listZeroRefs failed (bundle: ' + bundle + ', driver: '
958
+ + driverName + '): ' + ((err && err.message) || err)
959
+ + ' — if this names a missing index, run: ' + ddlLines()[0]);
960
+ return fn(err);
961
+ }
962
+ fn(null, rows.map(function(r) { return r.k; }));
963
+ });
964
+ },
965
+
966
+ /**
967
+ * Delete the row ONLY IF its refcount is still 0 — the sweep's claim
968
+ * step, and the reason concurrent sweeps across processes are safe
969
+ * without an election: the CAS guard makes exactly one claim win.
970
+ *
971
+ * A concurrent `acquireRef` resurrection wins the same way: it moves
972
+ * the document's CAS, this guarded remove reports `CasMismatchError`,
973
+ * and the sweep skips the blob.
974
+ *
975
+ * @param {string} key - The blob key.
976
+ * @param {function} [fn] - `fn(err, removed: boolean)`.
977
+ * @returns {void}
978
+ */
979
+ removeIfZero: function(key, fn) {
980
+ fn = once(fn);
981
+ var d = docIdFor(key);
982
+ if (d.error) { return fn(d.error); }
983
+
984
+ withCollection(function(coll) {
985
+ return coll.get(d.id).then(function(res) {
986
+ if ( res.content.refs !== 0 ) { return fn(null, false); }
987
+ return coll.remove(d.id, withDurability({ cas: res.cas }))
988
+ .then(function() { fn(null, true); })
989
+ .catch(function(err) {
990
+ // Both mean somebody else got there first — a
991
+ // resurrection (CAS moved) or another sweeper
992
+ // (document gone). Neither is an error.
993
+ if ( isCbError(err, 'CasMismatchError') || isCbError(err, 'DocumentNotFoundError') ) {
994
+ return fn(null, false);
995
+ }
996
+ fn(err);
997
+ });
998
+ }).catch(function(getErr) {
999
+ if ( isCbError(getErr, 'DocumentNotFoundError') ) { return fn(null, false); }
1000
+ fn(getErr);
1001
+ });
1002
+ }, fn);
1003
+ },
1004
+
1005
+ /**
1006
+ * Aggregate counts over this driver's rows — the `storage:stats`
1007
+ * operator surface. Reserved dot-key rows (the `.driver` stamp) are
1008
+ * excluded, so an empty root reports zero objects.
1009
+ *
1010
+ * @param {function} fn - `fn(err, {objects, refcounted, zeroRefPending, inline, bytes})`.
1011
+ * @returns {void}
1012
+ */
1013
+ stats: function(fn) {
1014
+ fn = once(fn);
1015
+ runQuery(statsStatement, [driverName], function(err, rows) {
1016
+ if (err) {
1017
+ console.error('[CouchbaseStorageStore] stats failed (bundle: ' + bundle + ', driver: '
1018
+ + driverName + '): ' + ((err && err.message) || err));
1019
+ return fn(err);
1020
+ }
1021
+ var row = rows[0] || {};
1022
+ fn(null, {
1023
+ objects : row.objects || 0,
1024
+ refcounted : row.refcounted || 0,
1025
+ zeroRefPending : row.zeroRefPending || 0,
1026
+ inline : row.inline || 0,
1027
+ bytes : row.bytes || 0
1028
+ });
1029
+ });
1030
+ },
1031
+
1032
+ /**
1033
+ * Page over this driver's object keys, ordered by key — the
1034
+ * enumeration `storage:verify` walks for its rows-without-files
1035
+ * direction. Reserved dot-key rows are excluded.
1036
+ *
1037
+ * @param {string} afterKey - Exclusive lower bound (`''` for the first page).
1038
+ * @param {number} limit - Page size cap.
1039
+ * @param {function} fn - `fn(err, string[])`.
1040
+ * @returns {void}
1041
+ */
1042
+ listKeys: function(afterKey, limit, fn) {
1043
+ fn = once(fn);
1044
+ runQuery(
1045
+ keysStatement(safeLimit(limit, 500)),
1046
+ [driverName, ( typeof afterKey === 'string' ) ? afterKey : ''],
1047
+ function(err, rows) {
1048
+ if (err) {
1049
+ console.error('[CouchbaseStorageStore] listKeys failed (bundle: ' + bundle + ', driver: '
1050
+ + driverName + '): ' + ((err && err.message) || err)
1051
+ + ' — if this names a missing index, run: ' + ddlLines()[1]);
1052
+ return fn(err);
1053
+ }
1054
+ fn(null, rows.map(function(r) { return r.k; }));
1055
+ }
1056
+ );
1057
+ },
1058
+
1059
+ /**
1060
+ * Release the cluster connection. NOT called on the request path —
1061
+ * provided for teardown and tests.
1062
+ *
1063
+ * @returns {void}
1064
+ */
1065
+ close: function() {
1066
+ try {
1067
+ if ( cluster && typeof cluster.close === 'function' ) {
1068
+ var p = cluster.close();
1069
+ if ( p && typeof p.catch === 'function' ) { p.catch(noop); }
1070
+ }
1071
+ } catch (e) { /* already closed */ }
1072
+ }
1073
+ };
1074
+ };