gina 0.5.25 → 0.5.26
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.
- package/CHANGELOG.md +17 -0
- package/README.md +22 -15
- package/ROADMAP.md +4 -3
- package/bin/cli +22 -1
- package/bin/cmd +11 -1
- package/bin/gina-init +1 -0
- package/framework/v0.5.26/VERSION +1 -0
- package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/js/gina.js +10 -6
- package/framework/{v0.5.25 → v0.5.26}/core/config.js +29 -5
- package/framework/{v0.5.25 → v0.5.26}/core/connectors/couchbase/index.js +48 -3
- package/framework/{v0.5.25 → v0.5.26}/core/controller/controller.render-json.js +4 -0
- package/framework/{v0.5.25 → v0.5.26}/core/controller/controller.render-nunjucks.js +4 -0
- package/framework/{v0.5.25 → v0.5.26}/core/controller/controller.render-swig.js +4 -0
- package/framework/{v0.5.25 → v0.5.26}/core/server.isaac.js +12 -0
- package/framework/{v0.5.25 → v0.5.26}/core/server.js +235 -1
- package/framework/{v0.5.25 → v0.5.26}/core/template/conf/settings.json +36 -0
- package/framework/{v0.5.25 → v0.5.26}/lib/authz-gate/src/main.js +169 -2
- package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/arguments.json +1 -0
- package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/help.txt +19 -6
- package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/mcp-start.js +47 -5
- package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/openapi.js +37 -4
- package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/init.js +28 -1
- package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/set.js +5 -0
- package/framework/{v0.5.25 → v0.5.26}/lib/connector-error/src/main.js +8 -4
- package/framework/{v0.5.25 → v0.5.26}/lib/logger/src/containers/mq/listener.js +32 -2
- package/framework/{v0.5.25 → v0.5.26}/lib/mcp-http/src/main.js +110 -11
- package/framework/{v0.5.25 → v0.5.26}/lib/merge/src/main.js +10 -6
- package/framework/{v0.5.25 → v0.5.26}/package.json +1 -1
- package/gna.js +4 -4
- package/llms.txt +10 -5
- package/package.json +3 -3
- package/resources/home/settings.json +1 -0
- package/schema/routing.json +20 -0
- package/schema/settings.json +13 -0
- package/utils/helper.js +1 -1
- package/framework/v0.5.25/VERSION +0 -1
- /package/framework/{v0.5.25 → v0.5.26}/AUTHORS +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/LICENSE +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/html/nolayout.html +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/html/static.html +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/img/android-chrome-192x192.png +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/img/android-chrome-512x512.png +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/img/apple-touch-icon.png +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/img/favicon-16x16.png +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/img/favicon-32x32.png +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/img/favicon.ico +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.css +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/beemaster/index.html +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/css/gina.min.css +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.br +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.gz +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/html/statusbar.html +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.br +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.gz +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/inspector/have_heart_one-webfont.woff2 +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/inspector/index.html +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/inspector/inspector.css +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/inspector/inspector.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/inspector/logo.svg +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/js/gina.min.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.br +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.gz +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/ai/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/ai/lib/connector.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/couchbase/lib/connector.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/couchbase/lib/connector.v3.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/couchbase/lib/connector.v4.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/couchbase/lib/n1ql.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/couchbase/lib/session-store.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/couchbase/lib/session-store.v3.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/couchbase/lib/session-store.v4.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/mongodb/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/mongodb/lib/connector.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/mongodb/lib/job-store.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/mongodb/lib/pipeline-loader.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/mongodb/lib/session-store.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/mysql/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/mysql/lib/connector.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/postgresql/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/postgresql/lib/connector.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/redis/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/redis/lib/connector.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/redis/lib/job-store.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/redis/lib/render-cache-store.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/redis/lib/session-store.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/scylladb/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/scylladb/lib/connector.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/scylladb/lib/session-store.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/sql-parser.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/sqlite/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/sqlite/lib/connector.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/sqlite/lib/job-store.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/connectors/sqlite/lib/session-store.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/content.encoding +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/controller/controller.framework.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/controller/controller.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/controller/controller.render-nunjucks-async.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/controller/controller.render-stream.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/controller/controller.render-swig-async.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/controller/controller.render-v1.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/controller/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/controller/inspector-window-emit.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/controller/release-banner.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/dev/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/dev/lib/class.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/dev/lib/factory.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/dev/lib/tools.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/gna.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/locales/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/locales/currency.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/locales/dist/language/en.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/locales/dist/language/fr.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/locales/dist/region/en.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/locales/dist/region/fr.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/locales/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/mime.types +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/model/entity.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/model/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/model/template/entityFactory.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/model/template/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/csrf/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/csrf/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/csrf/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/coep/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/coep/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/coep/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/coop/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/coop/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/coop/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/corp/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/corp/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/corp/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/csp/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/csp/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/csp/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/hide-powered-by/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/hide-powered-by/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/hide-powered-by/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/hsts/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/hsts/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/hsts/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/origin-agent-cluster/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/origin-agent-cluster/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/origin-agent-cluster/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/referrer-policy/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/referrer-policy/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/referrer-policy/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-content-type-options/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-content-type-options/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-content-type-options/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-dns-prefetch-control/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-dns-prefetch-control/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-dns-prefetch-control/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-download-options/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-download-options/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-download-options/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-frame-options/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-frame-options/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-frame-options/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-xss-protection/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-xss-protection/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/x-xss-protection/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/session/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/session/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/session/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/storage/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/storage/build.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/storage/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/storage/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/validator/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/validator/build.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/validator/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/validator/src/form-validator.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/validator/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/router.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/server.express.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/status.codes +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/_gitignore +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle/config/app.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle/config/connectors.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle/config/routing.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle/config/settings.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle/config/settings.server.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle/config/templates.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle/config/watchers.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle/controllers/controller.content.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle/controllers/controller.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle/controllers/setup.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle/locales/en.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle_namespace/controllers/controller.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle_public/css/default.css +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle_public/css/home.css +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle_public/css/vendor/readme.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle_public/favicon.ico +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle_public/js/components/x-checklist.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle_public/js/vendor/readme.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle_public/manifest.webmanifest +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle_public/readme.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle_public/sw.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle_templates/handlers/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle_templates/html/content/homepage.html +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle_templates/html/includes/error-msg-noscript.html +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle_templates/html/includes/error-msg-outdated-browser.html +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle_templates/html/includes/x-checklist.html +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/boilerplate/bundle_templates/html/layouts/main.html +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/command/gina.bat.tpl +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/command/gina.tpl +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/conf/env.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/conf/manifest.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/conf/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/conf/statics.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/conf/templates.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/error/client/json/401.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/error/client/json/403.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/error/client/json/404.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/error/server/html/50x.html +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/error/server/json/500.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/error/server/json/503.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/core/template/extensions/logger/config.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/console.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/context.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/data/LICENSE +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/data/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/data/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/data/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/dateFormat.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/json/LICENSE +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/json/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/json/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/json/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/path.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/plugins/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/plugins/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/plugins/src/api-error.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/plugins/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/prototypes.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/task.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/helpers/text.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/admin/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/admin/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/archiver/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/archiver/build.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/archiver/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/archiver/src/dep/jszip.min.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/archiver/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/async/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/async/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/audit/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/audit/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/audit-store.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/authz-gate/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cache/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cache/build.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cache/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cache/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/aliases.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/add.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/build.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/copy.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/cp.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/help.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/inc/name-rewrite.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/list.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/man.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/mcp.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/oas.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/remove.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/rename.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/restart.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/rm.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/start.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/status.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/stop.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/bundle/types.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/cache/arguments.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/cache/clear.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/cache/help.txt +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/cache/stats.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/connector/add.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/connector/arguments.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/connector/help.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/connector/help.txt +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/connector/infer.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/connector/list.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/connector/migrate.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/connector/models.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/connector/remove.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/connector/rm.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/connector/test.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/container/arguments.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/container/help.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/container/help.txt +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/container/man.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/container/ps.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/container/stop.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/controller/add.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/controller/arguments.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/controller/help.txt +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/controller/inc/args.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/controller/inc/namespace.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/controller/inc/reference-rewrite.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/controller/inc/reference-scan.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/controller/inc/scaffold.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/controller/remove.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/controller/rename.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/controller/rm.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/env/add.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/env/get.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/env/help.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/env/help.txt +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/env/link-dev.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/env/list.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/env/remove.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/env/rm.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/env/set.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/env/unset.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/env/use.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/add.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/arguments.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/build.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/dot.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/get.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/help.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/help.txt +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/link-node-modules.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/link.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/list.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/man.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/msg.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/open.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/remove.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/reset.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/restart.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/start.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/status.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/stop.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/tail.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/update.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/framework/version.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/gina-dev.1.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/gina-framework.1.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/gina.1.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/helper.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/i18n/add.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/i18n/arguments.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/i18n/export.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/i18n/help.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/i18n/help.txt +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/i18n/import.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/i18n/scan.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/image/_host.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/image/arguments.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/image/build.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/image/help.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/image/help.txt +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/image/list.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/image/man.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/image/rm.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/image/run.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/inspector/help.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/inspector/help.txt +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/inspector/open.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/man-render.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/minion/arguments.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/minion/help.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/minion/help.txt +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/minion/kill.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/minion/list.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/msg.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/port/help.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/port/help.txt +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/port/inc/scan.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/port/list.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/port/reset.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/port/set.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/add.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/arguments.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/backup.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/build.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/help.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/help.txt +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/import.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/list.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/man.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/move.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/remove.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/rename.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/restart.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/restore.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/rm.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/start.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/status.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/project/stop.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/protocol/arguments.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/protocol/help.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/protocol/help.txt +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/protocol/list.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/protocol/remove.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/protocol/set.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/scope/add.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/scope/help.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/scope/help.txt +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/scope/link-local.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/scope/link-production.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/scope/list.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/scope/remove.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/scope/rm.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/scope/use.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/secrets/arguments.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/secrets/check.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/secrets/help.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/secrets/help.txt +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/secrets/scan.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/service/help.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/service/help.txt +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/service/list.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/service/man.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/service/start.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd/view/add.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd-status-format/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cmd-status-format/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/collection/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/collection/build.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/collection/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/collection/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/config.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/connector-config/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/connector-config/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/connector-error/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/connector-registry/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/connector-registry/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cron/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cron/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/cron/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/domain/LICENSE +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/domain/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/domain/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/domain/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/dto/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/dto/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/dto-pipe/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/dto-pipe/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/dto-types/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/dto-types/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/generator/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/i18n/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/i18n/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/image-build/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/image-build/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/inherits/LICENSE +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/inherits/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/inherits/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/inherits/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/inspector-events/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/inspector-events/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/inspector-redact/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/inspector-redact/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/instrument/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/instrument/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/job/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/job/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/job-store.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/json-config-header/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/json-config-header/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/logger/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/logger/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/logger/src/containers/default/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/logger/src/containers/file/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/logger/src/containers/file/lib/logrotator/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/logger/src/containers/file/lib/logrotator/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/logger/src/containers/mq/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/logger/src/containers/mq/speaker.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/logger/src/helper.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/logger/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/math/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/mcp-dispatch/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/mcp-dispatch/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/mcp-http/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/mcp-server/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/mcp-server/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/merge/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/merge/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/metrics/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/metrics/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/model.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/nunjucks-filters/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/nunjucks-filters/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/nunjucks-filters/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/nunjucks-resolver/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/nunjucks-resolver/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/proc.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/release-watch/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/release-watch/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/render-cache/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/render-cache/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/render-cache-store.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/routing/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/routing/build.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/routing/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/routing/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/routing/src/radix.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/routing-introspect/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/routing-introspect/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/secrets/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/secrets/src/backends/env.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/secrets/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/session-store.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/shell.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/state.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/swig-filters/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/swig-filters/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/swig-filters/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/swig-resolver/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/swig-resolver/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/template-loaders/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/template-loaders/src/loaders/http.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/template-loaders/src/loaders/memory.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/template-loaders/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/url/README.md +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/url/index.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/url/routing.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/uuid/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/uuid/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/validator.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/watcher/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/watcher/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/ws-framing/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/ws-framing/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/ws-query/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/ws-query/src/main.js +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/ws-session/package.json +0 -0
- /package/framework/{v0.5.25 → v0.5.26}/lib/ws-session/src/main.js +0 -0
package/llms.txt
CHANGED
|
@@ -512,7 +512,7 @@ Output path override: `--output=/path/to/mcp.json`.
|
|
|
512
512
|
|
|
513
513
|
`gina bundle:mcp-start <bundle> @<project>` runs a live Model Context Protocol server for a single bundle over stdio (MCP spec revision **2025-06-18**, JSON-RPC 2.0, newline-delimited UTF-8). It reads `<bundle>/config/mcp.json` (written by `bundle:mcp`) and dispatches incoming `tools/call` requests as real HTTP requests against the running bundle's configured port on localhost.
|
|
514
514
|
|
|
515
|
-
**Prerequisites.** The bundle must already be running (`gina bundle:start`) and the manifest must exist (`gina bundle:mcp`). The server is stateless — it holds no session, no auth, nothing beyond what lives in `mcp.json` and the bundle's own routing.
|
|
515
|
+
**Prerequisites.** The bundle must already be running (`gina bundle:start`) and the manifest must exist (`gina bundle:mcp`). The server is stateless — it holds no session, no auth on the stdio wire (see the HTTP transport below for its bearer + Origin gates), nothing beyond what lives in `mcp.json` and the bundle's own routing.
|
|
516
516
|
|
|
517
517
|
**Stdio discipline.** An early intercept in `bin/cli` detects `bundle:mcp-start` in argv and redirects `process.stdout.write` to stderr before any framework module loads, stashing the real write on `process.__ginaMcpStdout`. The MCP wire uses the stashed write; framework logger output, bootstrap noise, and stray `console.log` calls all land on stderr, which MCP clients ignore. Without this, a single log line corrupts the JSON-RPC parser on the client side.
|
|
518
518
|
|
|
@@ -524,7 +524,7 @@ Output path override: `--output=/path/to/mcp.json`.
|
|
|
524
524
|
|
|
525
525
|
Baseline architecture lives in two new libs: `lib/mcp-server/` (transport-agnostic JSON-RPC + lifecycle) and `lib/mcp-dispatch/` (HTTP loopback). Both are registered in `lib.mcpServer` / `lib.mcpDispatch` — **go through the registry, bare-module resolution does not work in CLI daemon scope**.
|
|
526
526
|
|
|
527
|
-
Streamable HTTP transport (MCP Phase 2b) shipped in 0.3.7 — `bundle:mcp-start --transport=http` (library `lib/mcp-http`; flags `--http-host`/`--http-port`/`--auth-token`/`--cors-origin`/`--max-in-flight`).
|
|
527
|
+
Streamable HTTP transport (MCP Phase 2b) shipped in 0.3.7 — `bundle:mcp-start --transport=http` (library `lib/mcp-http`; flags `--http-host`/`--http-port`/`--auth-token`/`--cors-origin`/`--max-in-flight`/`--allow-insecure`). **Fail-closed start gate:** the transport binds loopback and enforces a built-in `Origin` allowlist, and a bearer token is optional on that default because those two ARE the protection — but remove either (a non-loopback `--http-host`, or `--cors-origin=*`, which disables the only defence against DNS rebinding: a loopback bind does not help there, the browser is already local) and `start()` REJECTS unless a token is configured or `--allow-insecure` / `mcp.json > server > allowInsecure` (strict boolean) asserts an upstream boundary — a mesh, a NetworkPolicy, or an authenticating reverse proxy. It refuses BEFORE binding, so no unauthenticated port is ever reachable. Bearer validation sha256-hashes BOTH sides before `timingSafeEqual`, so the compare is fixed-length and cannot short-circuit on token length. **Read `GINA_MCP_AUTH_TOKEN` via `getEnvVar`, never `process.env`** — `filterArgs()` (`bin/cli`) moves every `GINA_*` key into `process.gina` and DELETES it from `process.env`, so a direct read is always undefined under the CLI and the token silently never applies; the same sweep makes any `${secret:GINA_*}` placeholder unresolvable (that one fails closed, refusing to boot). For the same reason `resolveHttpHost`'s `GINA_HOST_V4` tier is inert — deliberately left so, since `host_v4` is the address clients CONNECT to (often a LAN address) and reviving it would move the default bind off loopback.
|
|
528
528
|
|
|
529
529
|
---
|
|
530
530
|
|
|
@@ -941,7 +941,7 @@ Dev-mode query instrumentation captures every database query tied to the current
|
|
|
941
941
|
|
|
942
942
|
250. **The module-level `gina.emit` (`require('gina').emit`) is an inert stub — always returns `false`, never dispatches, never throws; the module object is a plain literal with NO `on`/`once`, so it is not an event surface — application events go through the controller's `self.emitEvent()` (#B109, fixed 2026-07-16).** Pre-fix it was a DETACHED copy of the internal lifecycle emitter's `emit` (`this` at call time = the plain module object, no `_events`): it returned false for every name EXCEPT `'error'`, which THREW its argument via Node's unhandled-`'error'` path (ERR_UNHANDLED_ERROR when called bare) — a synchronous crash landmine on the most guessable call of an error-reporting-shaped API. Binding it instead (`e.emit.bind(e)`) was REJECTED by consumer survey: zero callers existed anywhere (framework, services, scaffolding boilerplate, every known consumer), and binding would have opened dispatch INTO the framework's internal lifecycle listeners (a consumer `emit('complete')` would re-run the server-start continuation with a bogus instance; `emit('error')` would invoke the framework error handler with undefined request/response). Rule: a detached EventEmitter method copy (`x.emit = emitter.emit`) is never a working event API — `this` rebinds at the call site; either `.bind()` it deliberately (only with a listener surface and real demand) or stub it inert.
|
|
943
943
|
|
|
944
|
-
251. **Route authorization gate — `param.requireAuth` / `param.roles` / `param.policy` (#COMPLY1 slices 1-3, 2026-07-16/17, unreleased).** A route requires an authenticated session by declaring `"requireAuth": true` in its routing.json `param` block; `lib/authz-gate` (plain-required in lib/index.js, the dtoPipe precedent) enforces it at BOTH `core/router.js` dispatch sites immediately BEFORE `dtoPipe.validateRequestPayload` — the invariant is **401/403 → 422 → controller** (an unauthenticated caller must never learn whether its payload would have validated; a 422 field map is a disclosure). Strict NO-OP for any route that declares nothing. **Contract: authenticated ⇔ `req.session.user` truthy** — read DIRECTLY, never through router.js's conditionally-installed Passport `request.isAuthenticated()` shim (zero framework callers, measured; it itself converges onto `request.session.user`). **The placement decision that dissolved the dist rebuild:** `param.requireAuth`, NOT a top-level csrfExempt-style flag. `param` rides the existing whole-param clone on both cold (`server.js` `param:JSON.clone(routing[name].param)`) and warm (`getCached`) paths, so a new `param.*` key needs ZERO `lib/routing` edits — measured empty dist-pathspec status, `lib/routing` untouched, no bundle-freshness exposure (the `param.dto` precedent; the top-level `csrfExempt` shape would have cost the two-site propagation edit + a prod dist rebuild because `lib/routing` is browser-bundled). Rule: a new per-route flag belongs in `param` unless it genuinely needs to be top-level (COMPLY6 `rateLimit` should default the same). **On-fail:** 401 `throwError({status:401,error:'Authentication required'})` by default; for a BROWSER navigation with a configured `settings.json > auth.loginRoute` AND an existing `req.session`, a hand-emitted login bounce — NOT `controller.redirect()`, which defaults to a **cacheable 301** (`req.routing.param.code || 301`) with a dev-or-proxied-GATED no-store (#B68), i.e. a login LOOP on a direct-prod deployment (the browser replays the 301 for the later authenticated visit). The gate emits it directly, mirroring redirect()'s exit (`res.writeHead(code,headInfos)` on both engines + `res.end(JSON.stringify({status,headers}))` — the body the inter-bundle `query()` 3xx intercept parses — + the `console.info('<METHOD> [302] <path>')` pod-log line) with the status FORCED to 302 and the no-store set UNCONDITIONAL. The request is `pauseRequest`-snapshotted first so the login action replays it via `self.resumeRequest()`. **The bounce needs all THREE** (else 401): a configured target; NOT an XHR (`req.isXMLRequest` — an XHR follows a Location transparently and would get the login PAGE as its body; measured a bundle with no Session plugin → 401s, never bounces because pauseRequest 424s without a session). **Boot-resolve + fail-fast lint** in `core/server.js` (the `_dtos`/`_adminAllowList` mould): `process.gina._authConf = {loginRoute}` resolved ONCE (O(1) request read, no per-request config clone an unauth caller could amplify); a non-boolean `requireAuth` (a truthy STRING is the motivating case — the gate tests `=== true`, so `"requireAuth":"true"` would silently NOT gate), a non-object `auth`, an unknown/multi-url/parameterized `loginRoute` all REFUSE TO BOOT (#B57 shape). **Two traps a unit test could not catch, caught by the live daemonless boot:** (a) `core/config.js:2086-2091` re-keys every rule to `<rule.toLowerCase()>@<bundle>` at normalisation — a lookup of the declared name (`login`) misses, must be `login@web` (the resolve accepts both); (b) `config.js:2138` already composes the bundle webroot INTO `routing[rule].url`, so a rule-name loginRoute resolves to the real served path for free (`login` → `/web/login`), while an absolute path is verbatim — either way root-relative ⇒ same-origin ⇒ clear of the #B65/#B66/#B67 proxy-host family. Server-side only (no dist rebuild); `settings.json > auth` change needs a bundle restart (boot config). Live-verified matrix (ungated 200 / browser-bounce 302+no-store / snapshot / signed-in 200 / XHR 401 / no-Session-plugin 401 / bad-loginRoute boot-emerg). Slice 2 adds `param.roles: ["admin","editor"]` — ANY-of match against `req.session.user.roles` (opaque strings, no framework vocabulary, no role→permission indirection in v1), which IMPLIES requireAuth (evaluation order authN → roles: unauthenticated → the 401/bounce, authenticated-but-role-less → a 403 whose body stays GENERIC — the required roles are never echoed to the wire; the denial detail goes to a server-side console.debug line naming the rule). The boot lint refuses every declared-but-invalid `roles` shape (null / bare string / empty array / non-string or empty-string members — each would otherwise be silently ungated, the truthy-string class). And the boot-built client routing maps (`/_gina/assets/routing.json` — the full map AND the #B66 host-stripped variant, which is cloned FROM the full map AFTER the strip so both inherit it) no longer ship `requireAuth`/`roles`/`policy` to the browser: they name the authorization model, and the client bundle reads none of them (measured: zero readers in src and in the built artifacts). **Slice 3 adds `param.policy: "<name>"`** — the record/attribute escape hatch RBAC cannot express (ownership etc.): `<bundle>/policies/<name>.js` exporting `module.exports = function (user, req) { return boolean; }`, registered at BOOT via `lib.authzGate.registerPolicy(bundleSrcPath, name)` (the `lib.dto.load` mould — returns null when unresolved, THROWS when present-but-broken, caller adds route context) onto `process.gina._policies`, so the request path is an O(1) lookup — no fs, no re-require (which would also feed the dev-mode `module.children` leak class #B32). IMPLIES requireAuth and AND-composes AFTER roles (**authN → roles → policy**; a role denial never runs the policy). **The signature is SYNCHRONOUS because the GATE is** (`authorizeRequest` returns a boolean both `router.js` sites branch on directly), and TWO rules make that safe rather than merely convenient — the measured asymmetry is the whole design: a native `async function` policy reads `constructor.name === 'AsyncFunction'` (the ONLY boot-visible tell — `typeof` says `'function'` for both, measured) so it is **refused at boot**; but a policy that merely RETURNS a promise (the transpiled-async shape) reads `constructor.name === 'Function'` and is **boot-INVISIBLE**, so the allow test is strictly `=== true` — a promise is truthy but not `true`, and a **truthy-allow gate would ALLOW it unconditionally: the quietly-OFF class INVERTED into fail-OPEN** (live-measured: a promise-returning policy whose answer was `true` boots fine and then 403s every request, warning ONCE; a `!!allowed` gate would have allowed a request the policy explicitly DENIED). A non-boolean return warns once per policy naming it (a per-request warn would bury the message it exists to surface); a THROWING policy denies 403 + `console.error` and never 500s the wire nor kills the bundle. Every slice-3 denial keeps the generic 403 — the **policy name never reaches the wire** (measured live: 0 occurrences of the policy name, the rule name, or even the policy's own thrown error text in the 403 body, against a `Forbidden`-fires-twice control); the detail goes to the server-side `[ authz ] denied \`<rule>\` — policy \`<name>\` did not allow|threw` line. Boot lint refuses a non-string/empty `policy`, a missing file, a non-function export and an async policy (#B57 shape) — all four live-verified `exit=1`. `self.hasRole(role)` is the imperative escape hatch for an action authorizing mid-logic: it **delegates to the gate's exported `hasAnyRole`** rather than re-reading `user.roles` itself (one definition of "holding a role" framework-wide — the byte-identical-copy-paste class `lib/cmd-status-format`/`lib/json-config-header` were extracted to end) and carries the #B35 released-response guard (`local.req == null` → false); its `types/index.d.ts` SuperController member is MANDATORY — the #DTO3b parity gate diffs the interface against a real instance. Server-side only, no dist rebuild (slice 2 already strips `policy` from the client blobs). Tests 65→110 (`test/lib/authz-gate.test.js` §11-§13; the roles-before-policy ordering pin + the delegation pin both validated can-fail against verified-changed perturbed copies). **#MS3 (2026-07-24, unreleased) adds MACHINE-CALLER authentication to the same gate** — service-to-service callers that cannot hold a session: `settings.json > auth.machine` (STRICTLY opt-in; `enabled` boolean-linted, fail-closed) declares named callers (`"callers": { "<name>": { "key": "<${secret:KEY}-capable>", "roles": [...] } }`); a GATED session-less request presenting `Authorization: Bearer <key>` is verified against a BOOT-precomputed sha256 hash per caller (on `process.gina._authConf.machine` — the request path compares fixed-length digests via `crypto.timingSafeEqual`: hash-BOTH-sides so no length oracle, raw keys not retained past boot, an invalid token pays the full caller scan) and becomes the effective principal `{ name, roles, machine: true }` stamped on `req.machineCaller` — it satisfies `requireAuth`, its configured roles ride the SAME ANY-of match, policies receive it as their `user` argument (discriminate via `user.machine === true`), audit actors snapshot `{ key: <callerName>, roles, machine: true }`, and `self.hasRole()` answers its roles. SESSION WINS (a signed-in request never consults the machine path); resolution is LAZY (un-gated routes never pay a compare); `enabled: false` and a pre-#MS3 `_authConf` shape are byte-identical legacy (both subtract-locked). A presented-but-invalid Bearer gets a clean 401 + `WWW-Authenticate: Bearer` and NEVER the login bounce (the '401-machine' audit outcome); a custom-scheme miss degrades to the ordinary 401/bounce — the machine 401 stays Bearer-specific. **Deliberately NO per-route opt-in key**: per-route granularity rides `roles` (keep a route human-only by requiring a role no caller holds, machine-only by one only callers hold). The escape hatch — `auth.machine.authenticator` names `<bundle>/authenticators/<name>.js` (the `policies/<name>.js` shape applied to authN): a SYNCHRONOUS `function (req) { return { name, roles } | null; }` run AFTER the built-in map (first success wins) and REGARDLESS of Bearer presence, so it verifies any sync-checkable credential (a sync-`verify` JWT, an HMAC header, an x-api-key); its return is NORMALIZED (`machine: true` forced, non-array roles collapse to `[]`), an `async function` module REFUSES the boot (the policy asymmetry: the transpiled-async promise shape is boot-invisible, which is why the runtime shape check stays strict), and a throw or malformed return at request time is fail-closed unauthenticated (warn-once), never a 500. `schema/settings.json` gains the previously-undeclared `auth` block (loginRoute + machine). Server-side only, no dist rebuild; `auth.machine` is boot config (restart to change). Tests: `test/lib/authz-gate-machine.test.js` (52 — session-wins + never-bounce decisive fixtures, both subtracts, the hash-of-key non-admission control, map-first spy proof, real-audit machine actors, controller hasRole via createTestInstance).
|
|
944
|
+
251. **Route authorization gate — `param.requireAuth` / `param.roles` / `param.policy` (#COMPLY1 slices 1-3, 2026-07-16/17, unreleased).** A route requires an authenticated session by declaring `"requireAuth": true` in its routing.json `param` block; `lib/authz-gate` (plain-required in lib/index.js, the dtoPipe precedent) enforces it at BOTH `core/router.js` dispatch sites immediately BEFORE `dtoPipe.validateRequestPayload` — the invariant is **401/403 → 422 → controller** (an unauthenticated caller must never learn whether its payload would have validated; a 422 field map is a disclosure). Strict NO-OP for any route that declares nothing. **Contract: authenticated ⇔ `req.session.user` truthy** — read DIRECTLY, never through router.js's conditionally-installed Passport `request.isAuthenticated()` shim (zero framework callers, measured; it itself converges onto `request.session.user`). **The placement decision that dissolved the dist rebuild:** `param.requireAuth`, NOT a top-level csrfExempt-style flag. `param` rides the existing whole-param clone on both cold (`server.js` `param:JSON.clone(routing[name].param)`) and warm (`getCached`) paths, so a new `param.*` key needs ZERO `lib/routing` edits — measured empty dist-pathspec status, `lib/routing` untouched, no bundle-freshness exposure (the `param.dto` precedent; the top-level `csrfExempt` shape would have cost the two-site propagation edit + a prod dist rebuild because `lib/routing` is browser-bundled). Rule: a new per-route flag belongs in `param` unless it genuinely needs to be top-level (COMPLY6 `rateLimit` should default the same). **On-fail:** 401 `throwError({status:401,error:'Authentication required'})` by default; for a BROWSER navigation with a configured `settings.json > auth.loginRoute` AND an existing `req.session`, a hand-emitted login bounce — NOT `controller.redirect()`, which defaults to a **cacheable 301** (`req.routing.param.code || 301`) with a dev-or-proxied-GATED no-store (#B68), i.e. a login LOOP on a direct-prod deployment (the browser replays the 301 for the later authenticated visit). The gate emits it directly, mirroring redirect()'s exit (`res.writeHead(code,headInfos)` on both engines + `res.end(JSON.stringify({status,headers}))` — the body the inter-bundle `query()` 3xx intercept parses — + the `console.info('<METHOD> [302] <path>')` pod-log line) with the status FORCED to 302 and the no-store set UNCONDITIONAL. The request is `pauseRequest`-snapshotted first so the login action replays it via `self.resumeRequest()`. **The bounce needs all THREE** (else 401): a configured target; NOT an XHR (`req.isXMLRequest` — an XHR follows a Location transparently and would get the login PAGE as its body; measured a bundle with no Session plugin → 401s, never bounces because pauseRequest 424s without a session). **Boot-resolve + fail-fast lint** in `core/server.js` (the `_dtos`/`_adminAllowList` mould): `process.gina._authConf = {loginRoute}` resolved ONCE (O(1) request read, no per-request config clone an unauth caller could amplify); a non-boolean `requireAuth` (a truthy STRING is the motivating case — the gate tests `=== true`, so `"requireAuth":"true"` would silently NOT gate), a non-object `auth`, an unknown/multi-url/parameterized `loginRoute` all REFUSE TO BOOT (#B57 shape). **Two traps a unit test could not catch, caught by the live daemonless boot:** (a) `core/config.js:2086-2091` re-keys every rule to `<rule.toLowerCase()>@<bundle>` at normalisation — a lookup of the declared name (`login`) misses, must be `login@web` (the resolve accepts both); (b) `config.js:2138` already composes the bundle webroot INTO `routing[rule].url`, so a rule-name loginRoute resolves to the real served path for free (`login` → `/web/login`), while an absolute path is verbatim — either way root-relative ⇒ same-origin ⇒ clear of the #B65/#B66/#B67 proxy-host family. Server-side only (no dist rebuild); `settings.json > auth` change needs a bundle restart (boot config). Live-verified matrix (ungated 200 / browser-bounce 302+no-store / snapshot / signed-in 200 / XHR 401 / no-Session-plugin 401 / bad-loginRoute boot-emerg). Slice 2 adds `param.roles: ["admin","editor"]` — ANY-of match against `req.session.user.roles` (opaque strings, no framework vocabulary, no role→permission indirection in v1), which IMPLIES requireAuth (evaluation order authN → roles: unauthenticated → the 401/bounce, authenticated-but-role-less → a 403 whose body stays GENERIC — the required roles are never echoed to the wire; the denial detail goes to a server-side console.debug line naming the rule). The boot lint refuses every declared-but-invalid `roles` shape (null / bare string / empty array / non-string or empty-string members — each would otherwise be silently ungated, the truthy-string class). And the boot-built client routing maps (`/_gina/assets/routing.json` — the full map AND the #B66 host-stripped variant, which is cloned FROM the full map AFTER the strip so both inherit it) no longer ship `requireAuth`/`roles`/`policy` to the browser: they name the authorization model, and the client bundle reads none of them (measured: zero readers in src and in the built artifacts). **Slice 3 adds `param.policy: "<name>"`** — the record/attribute escape hatch RBAC cannot express (ownership etc.): `<bundle>/policies/<name>.js` exporting `module.exports = function (user, req) { return boolean; }`, registered at BOOT via `lib.authzGate.registerPolicy(bundleSrcPath, name)` (the `lib.dto.load` mould — returns null when unresolved, THROWS when present-but-broken, caller adds route context) onto `process.gina._policies`, so the request path is an O(1) lookup — no fs, no re-require (which would also feed the dev-mode `module.children` leak class #B32). IMPLIES requireAuth and AND-composes AFTER roles (**authN → roles → policy**; a role denial never runs the policy). **The signature is SYNCHRONOUS because the GATE is** (`authorizeRequest` returns a boolean both `router.js` sites branch on directly), and TWO rules make that safe rather than merely convenient — the measured asymmetry is the whole design: a native `async function` policy reads `constructor.name === 'AsyncFunction'` (the ONLY boot-visible tell — `typeof` says `'function'` for both, measured) so it is **refused at boot**; but a policy that merely RETURNS a promise (the transpiled-async shape) reads `constructor.name === 'Function'` and is **boot-INVISIBLE**, so the allow test is strictly `=== true` — a promise is truthy but not `true`, and a **truthy-allow gate would ALLOW it unconditionally: the quietly-OFF class INVERTED into fail-OPEN** (live-measured: a promise-returning policy whose answer was `true` boots fine and then 403s every request, warning ONCE; a `!!allowed` gate would have allowed a request the policy explicitly DENIED). A non-boolean return warns once per policy naming it (a per-request warn would bury the message it exists to surface); a THROWING policy denies 403 + `console.error` and never 500s the wire nor kills the bundle. Every slice-3 denial keeps the generic 403 — the **policy name never reaches the wire** (measured live: 0 occurrences of the policy name, the rule name, or even the policy's own thrown error text in the 403 body, against a `Forbidden`-fires-twice control); the detail goes to the server-side `[ authz ] denied \`<rule>\` — policy \`<name>\` did not allow|threw` line. Boot lint refuses a non-string/empty `policy`, a missing file, a non-function export and an async policy (#B57 shape) — all four live-verified `exit=1`. `self.hasRole(role)` is the imperative escape hatch for an action authorizing mid-logic: it **delegates to the gate's exported `hasAnyRole`** rather than re-reading `user.roles` itself (one definition of "holding a role" framework-wide — the byte-identical-copy-paste class `lib/cmd-status-format`/`lib/json-config-header` were extracted to end) and carries the #B35 released-response guard (`local.req == null` → false); its `types/index.d.ts` SuperController member is MANDATORY — the #DTO3b parity gate diffs the interface against a real instance. Server-side only, no dist rebuild (slice 2 already strips `policy` from the client blobs). Tests 65→110 (`test/lib/authz-gate.test.js` §11-§13; the roles-before-policy ordering pin + the delegation pin both validated can-fail against verified-changed perturbed copies). **#MS3 (2026-07-24, unreleased) adds MACHINE-CALLER authentication to the same gate** — service-to-service callers that cannot hold a session: `settings.json > auth.machine` (STRICTLY opt-in; `enabled` boolean-linted, fail-closed) declares named callers (`"callers": { "<name>": { "key": "<${secret:KEY}-capable>", "roles": [...] } }`); a GATED session-less request presenting `Authorization: Bearer <key>` is verified against a BOOT-precomputed sha256 hash per caller (on `process.gina._authConf.machine` — the request path compares fixed-length digests via `crypto.timingSafeEqual`: hash-BOTH-sides so no length oracle, raw keys not retained past boot, an invalid token pays the full caller scan) and becomes the effective principal `{ name, roles, machine: true }` stamped on `req.machineCaller` — it satisfies `requireAuth`, its configured roles ride the SAME ANY-of match, policies receive it as their `user` argument (discriminate via `user.machine === true`), audit actors snapshot `{ key: <callerName>, roles, machine: true }`, and `self.hasRole()` answers its roles. SESSION WINS (a signed-in request never consults the machine path); resolution is LAZY (un-gated routes never pay a compare); `enabled: false` and a pre-#MS3 `_authConf` shape are byte-identical legacy (both subtract-locked). A presented-but-invalid Bearer gets a clean 401 + `WWW-Authenticate: Bearer` and NEVER the login bounce (the '401-machine' audit outcome); a custom-scheme miss degrades to the ordinary 401/bounce — the machine 401 stays Bearer-specific. **Deliberately NO per-route opt-in key**: per-route granularity rides `roles` (keep a route human-only by requiring a role no caller holds, machine-only by one only callers hold). The escape hatch — `auth.machine.authenticator` names `<bundle>/authenticators/<name>.js` (the `policies/<name>.js` shape applied to authN): a SYNCHRONOUS `function (req) { return { name, roles } | null; }` run AFTER the built-in map (first success wins) and REGARDLESS of Bearer presence, so it verifies any sync-checkable credential (a sync-`verify` JWT, an HMAC header, an x-api-key); its return is NORMALIZED (`machine: true` forced, non-array roles collapse to `[]`), an `async function` module REFUSES the boot (the policy asymmetry: the transpiled-async promise shape is boot-invisible, which is why the runtime shape check stays strict), and a throw or malformed return at request time is fail-closed unauthenticated (warn-once), never a 500. `schema/settings.json` gains the previously-undeclared `auth` block (loginRoute + machine). Server-side only, no dist rebuild; `auth.machine` is boot config (restart to change). Tests: `test/lib/authz-gate-machine.test.js` (52 — session-wins + never-bounce decisive fixtures, both subtracts, the hash-of-key non-admission control, map-first spy proof, real-audit machine actors, controller hasRole via createTestInstance). **#COMPLY10 (2026-07-25, unreleased) adds an opt-in DENY-BY-DEFAULT mode to the same gate:** `settings.json > auth.requireAuthByDefault: true` INVERTS the strict-NO-OP above — an un-annotated route is GATED, and `param.public: true` is the explicit exemption. `public` is tested INSIDE the un-annotated branch, so precedence is STRUCTURAL: a route carrying `public` alongside an explicit gate key never reaches that branch and stays gated, i.e. a hand-built or tampered config still fails CLOSED without relying on the lint having run. It is a `param.*` key for the same measured reason `requireAuth` was (rides the whole-param clone on both cold and warm paths ⇒ zero `lib/routing` edits, no dist rebuild — a top-level key would have cost the two-site propagation edit AND a prod rebuild), and a POSITIVE marker rather than a reused `requireAuth: false`, so a reviewer can tell an audited exemption from a leftover (the `csrfExempt` rationale). **The mode is keyed PER BUNDLE** (`_authConf.byBundle`, read via `req.routing.bundle`) — merged mode runs every bundle in ONE process and `_authConf` is written once per `init()`, so a FLAT flag would let whichever bundle booted LAST decide the posture for all of them, silently un-gating a bundle that had opted in (a fail-OPEN; the write now merges into the existing map instead of replacing it). ⚠️ `public` is a strict-mode RESERVED WORD, so it cannot join the isaac client-map strip as a bare destructured binding (`const { public, ... }` is a SyntaxError — only a renamed binding compiles); it is stripped with a separate `delete cleanParam.public;`, which also leaves the pinned #COMPLY1 destructuring line byte-identical. Boot refuses three mode-specific contradictions: `public` + an explicit gate key (same axis, opposite answers, no safe precedence); a login route the mode would gate (it bounces to ITSELF — an infinite redirect that locks out every visitor, so a rule-name target must be marked `public` and an unresolvable absolute path refuses, while NO `loginRoute` only WARNS since a pure API/machine bundle legitimately 401s everything); and **a mode-gated route that also declares `cache`** — both render-cache serve points run BEFORE the gate and `buildKey` is `<release>:<kind>:<bundle>:<url>` with NO principal component, so a cached gated route replays the first authenticated body to every later anonymous caller (scoped to the mode, so an EXPLICITLY gated cached route is not newly refused — that pre-existing exposure is tracked separately). The five framework-injected routes (`webroot@<bundle>` — which also matches `/` under `webrootAutoredirect` — `custom-error-page`, `bundle-status`, and both upload routes) ship `param.public: true`, so flipping the mode cannot take the site root or the error renderer offline. `bundle:openapi` threads the mode into its gated predicate, so the emitted spec can never declare a newly-gated route unauthenticated. Server-side only, no dist rebuild (measured: `authorizeRequest` appears 0× in the built browser artifact against a firing `csrfExempt` control); boot config, restart to change. **#B158 — a GATED route may not also declare `cache`, however it is gated (0.5.26).** Both render-cache serve points run BEFORE the gate — the engine-agnostic read serves and RETURNS ahead of `router.route` (inside which the gate runs), and isaac's runs pre-routing, before `req.routing` exists — and `buildKey` composes `<release>:<kind>:<bundle>:<url>` with NO principal component, so a cached gated route replayed the first authenticated caller's rendered body verbatim to every later anonymous one (reproduced live on an isolated boot: a Bearer-authenticated render, same body and same render nonce, served to an unauthenticated caller, while the identical route WITHOUT `cache` correctly 401'd). The boot lint now REFUSES the pairing in both modes (`auth.requireAuthByDefault` had covered only mode-gated routes; the explicitly annotated case it left open was the pre-existing hole) — **ACTION REQUIRED: such a bundle will not start** until `cache` is dropped or the route opened. Second layer: `lib/authz-gate` exports `isRouteGated(req)` (the one runtime answer — explicit key, else `param.public`, else the per-bundle mode) and all three render delegates consult it inside their `writeCache` guard, so a config that never passed the lint (hand-built, tampered, mutated at runtime) still fails CLOSED. **#B159 — an authorization key on a `method: "ws"` route REFUSES the boot (0.5.26).** A ws route is registered on the engine's extended-CONNECT handler and never reaches `handle()`/`router.route`, so `requireAuth`/`roles`/`policy` on one are unenforceable BY CONSTRUCTION — and it previously linted clean, booted, AND was counted in the `Registered N authorization-gated route(s)` line, so the framework actively CONFIRMED an illusion. Refused now (the truthy-string-`requireAuth` precedent: a structurally-OFF gate must refuse exactly like a silently-OFF one), keyed on `/^ws$/i` — byte-identical to the ws registrar's own predicate so the two can never disagree — placed after the policy block so one check covers all three keys. Remedy: authenticate in the `wsHandler`, which receives the full request. The MODE half is a WARN, not a refusal (an explicit key is an author asserting something false; `requireAuthByDefault` sweeps up every un-annotated route, so refusing would break a working ws bundle the moment the mode is switched on): ws routes are excluded from the deny-by-default tally and NAMED at boot instead. Live-verified both arms (refuses with the key, boots without). Tests: `authz-gate.test.js §17` (8 — replica + case-insensitivity + the `websocket`-is-not-`ws` boundary + source pins) and `§15` (20 — per-bundle isolation, structural precedence, a mode-OFF subtract-control, and a boot-lint replica; all 11 source pins + the headline behaviour red-armed against pre-fix source).
|
|
945
945
|
|
|
946
946
|
252. **Audit trail — `settings.json > audit` + `self.audit()` + authz auto-events (#COMPLY2 slices 1-2, 2026-07-17, unreleased).** A user-attributed append-only record of "who did what to which record when", DISTINCT from `lib/logger` (its own store; never the log sinks). Opt in with `audit.enabled: true` (STRICTLY boolean — a truthy `"true"` refuses to boot, the quietly-OFF class: a compliance control that silently does nothing is worse than one that is absent) and call `self.audit(action, data[, cb])`. **Record schema v1:** `{ id, ts, requestId, actor:{key,roles}, action, resource?, meta?, ip, rule, method, bundle, env }`. **The correlation key is the SHARED request id, not a second one:** slice 1 hoisted the existing `request._ginaReqId` stamp OUT of the `_reqCtxLogging` (JSON-log-mode) gate in `server.js` `onInstance` — always-on, both engines, **plus a first-seer `if (!request._ginaReqId)` guard** the gated stamp never had (it sits in the isaac double-dispatch spot ⇒ a re-entered dispatch REGENERATED the uuid; the hoist closes that latent hazard by construction). The `_reqALS` `.run()` stays JSON-gated, so the deferred always-on-ALS throughput question is untouched. One id, two consumers: audit records and JSON log lines correlate for free, and `_resolveRequestId`'s inbound `X-Request-Id` sanitization is reused — **so the id is client-influenceable BY DESIGN: it is correlation, never attribution** (attribution is the actor fields). **`rule` carries the re-keyed `<rule>@<bundle>` form** (`homepage@web`, `secure@web` — measured live), because `config.js` re-keys every rule at normalisation; a consumer grepping the trail must expect the suffix, not the bare routing.json key (same read as the #OBS1 metrics route label). `ip` is the socket remoteAddress, `::ffff:`-normalized — **`X-Forwarded-For` is NEVER read** (attacker-writable, the #OBS1 rule). `actor` is a SNAPSHOT of `session.user[audit.actorKey]` (default `"id"`) + a COPY of `user.roles`, never the whole user object (PII). **Default backend = append-only JSONL file**, path DERIVED as `<projectPath>/logs/audit-<bundle>-<env>.jsonl` — NOT read from `logsPath`, which is a **measured DEAD placeholder**: `env.json` declares it at the file ROOT, outside the `${bundle}`/`${env}` subtree config.js copies, nothing ever assigns it, so `${logsPath}` resolves to the literal string `"undefined"` and has zero template consumers (`projectPath` is inside the propagated subtree and provably resolves — it is what the live `bundlesPath` is built from). **Per-ENV filename is load-bearing:** two envs of one bundle running concurrently must never interleave writers into one file (harmless for JSONL, FATAL for the slice-3 hash chain). A relative `audit.file` resolves against the project root, never the process cwd (which depends on how the bundle was launched). **Writes are SERIALIZED** (FIFO, one in-flight `fs.write`): parallel writes on one fd complete in threadpool ORDER, and the chain needs on-disk order == emit order, so the queue ships in the MVP rather than with slice 3. `audit.store` (a connectors.json entry, resolved through the `lib/audit-store` dispatcher — the 3rd instance of the job-store mould) is wired from day 1 but **NO connector ships an implementation yet ⇒ configuring it is a clean boot REFUSAL**, never a silent fallback; `store`+`file` together is refused too (mutual exclusion, no silent precedence). **Framework auto-events are ON when audit is on:** the authz-gate deny sites emit `authz.denied` carrying `meta.outcome` (`401`|`login-bounce`|`403-roles`|`403-policy`|`401-machine` — the last added by #MS3's machine deny writer, whose records also carry the machine actor) — the real shape is **3 physical writers / 6 call sites / 5 outcomes** (`denyUnauthenticated`'s two exits + the SHARED `denyForbidden` with its explicit `outcome` arg + #MS3's `denyMachineUnauthenticated`), wired INSIDE the module by deep-path `require('../../audit/src/main')` because the deny helpers are unexported (the job→uuid precedent; one-way dep, no cycle). Opt out with `audit.events.authz: false`. The emit is fully contained (try/catch + enabled-gated), so **an audit failure can never change an authorization outcome** (locked by a subtract asserting identical thrown statuses with audit on vs off). Makes PCI 10.2.4 real with zero app code; the unauth-401 flood caveat is a throttling concern, not an audit one. **Two shapes worth copying:** (a) the boot lint `throw`s INSIDE `init()`'s try and INHERITS the #B57 emerg+`fs.writeSync(2,…)`+`exit(1)` from its enclosing catch — hand-rolling it would double-log and drop the `ServerEngine <stack>` prefix; (b) the boot destination line is `console.info`, NOT `.debug` — the shipped default `log_level: "info"` FILTERS debug, so a `.debug` would silently defeat the "path logged at boot" contract. `start()` is adopt-once (the `lib/job` precedent). **`self.audit()` on a released response emits a DEGRADED record** (req-derived fields null) instead of dropping — every req read in the record builder is null-safe by construction, so NO #B35 early-return: present-but-degraded beats absent for a compliance trail (the opposite of the render-path guards, deliberately). Server-side only — no dist rebuild. Live-verified daemonless: disabled = true no-op with an action calling `self.audit()`; enabled = full-schema record (real uuid requestId, socket ip, `<rule>@<bundle>`) + exactly one `authz.denied` on an unauth 401; `enabled:"true"` and an implementation-less `store` each refuse the boot with the exact emerg and never listen.
|
|
947
947
|
|
|
@@ -992,8 +992,13 @@ Dev-mode query instrumentation captures every database query tied to the current
|
|
|
992
992
|
275. **The `controller:` CLI group — `add` scaffolds, `remove`/`rm` reference-awarely deletes, `rename` reference-awarely renames a namespace controller (#R9, 2026-07-23).** `gina controller:add <name> <bundle> @<project> [--controls=a,b,c] [--api|--views]` — a new OFFLINE CLI group (`lib/cmd/controller/`, registered in `bin/cli` allowedOffline; a develop install serves the verb immediately, npm consumers at the next cut). Generates `controllers/controller.<name>.js` with one JSDoc'd action stub per `--controls` entry (omitted → a single `default` action — the `core/template/boilerplate/bundle_namespace` seed's own action name). Bundle FLAVOR auto-detected via `config/templates.json` presence (config.js's `hasViews` signal, offline-readable without a boot): a VIEW bundle → `self.render()` stubs + one template per action at `templates/html/<name>/<action>.html`; an API-only bundle → `self.renderJSON()` stubs, no templates. `--api`/`--views` force it (both → error). Route wiring is PRINT-ONLY: prints paste-ready rules keyed `<name>-<action>` carrying `namespace` + `param.control`, and for a VIEW rule an explicit `param.file: "<action>"` — render-swig.js:364-383 strips a `<namespace>-` prefix from a DEFAULTED `param.file` (which equals the rule name) and emits a per-request "does not respect gina naming convention" WARN, so the explicit file resolves `templates/html/<ns>/<action>.html` warn-free (the boilerplate `homepage` rule sidesteps it with a non-prefixed name); the `default` action's URL is the namespace root `/<name>`, else `/<name>/<action>`. Refuses an existing `controller.<name>.js` (no `--force` overwrite — remove it first), and validates the namespace charset `/^[a-z][a-z0-9_]*$/i` BEFORE any path build (`controller` reserved case-insensitively; the value is interpolated into file paths, a RegExp and a JS class name, so a loose value is an injection vector). Positionals come from the group's own pure `inc/args.js` parser (`opt.argv.slice(3)` minus `@project`/`--flags`) — CmdHelper's clean positional cleanup is `bundle:`-ONLY (helper.js:482), so `self.bundles` for any other topic is contaminated with the project's OTHER bundles and cannot be read for `<name> <bundle>`. Pure `inc/` helpers (`namespace` charset+className, `scaffold` parseControls/buildRules/formatRulesBlock/renderController/renderTemplate, `args` positionals) are require-by-path unit-tested behaviourally; the paste-ready report prints via flush-safe `fs.writeSync(1, …)` (the connector:infer precedent — a `console.log`/`process.stdout.write` before `process.exit` truncates on a pipe). Boot-verified end-to-end in an isolated home: the scaffolded view controller serves HTTP 200 with the rendered body and NO naming-convention warn. Tests: `test/lib/controller-add.test.js` (38). **`controller:remove <name> <bundle> @<project> [--dry-run] [--force] [--format=json]`** (alias `controller:rm` = `module.exports = require('./remove')`) is REFERENCE-AWARE: a namespace with no matching `controller.<name>.js` doesn't error — `router.js:521-525` WARNs and silently falls back to the default `controller.js` (a misdispatch), so a bare delete is unsafe. The pure `inc/reference-scan.js` (node `fs`/`path` only, no framework globals) scans the four measured reference sites — the controller file, routing.json rule-level `namespace` AND `param.namespace` (both load a controller; the body is comment-stripped with a STRING-AWARE regex so a `$schema` URL survives, and non-object entries are skipped like `config.js:2029`), and `requireController('<name>')` literals (both quote styles) across the bundle's `.js` tree — then REFUSES with a per-file blocker list unless clean (routing rules + external `requireController` calls block; a self-reference inside the file being deleted is moot). Clean → interactive readline yes/no (the `view:add` idiom; a non-TTY stdin aborts, naming `--force`/`--dry-run`) → deletes the controller file + its `templates/html/<name>/` tree. It NEVER edits routing.json. `--force` deletes the file+templates even with blockers (listing what remains to clean by hand), `--dry-run` previews, `--format=json` emits an envelope (`{controllerFile,templateDir,routingRefs,requireRefs,dynamicRefs,blocking,removable,removed}`) and deletes only with `--force`. Dynamic references a static scan cannot resolve (`param.namespace` `:variable`, non-literal `requireController(expr)`) are surfaced as an ADVISORY note, never silently cleared. The default `controller.js` can never be removed (`controller` is reserved). Deletion-plan file counts are taken BEFORE the delete. Tests: `test/lib/controller-remove.test.js` (34). **`controller:rename <old> <new> <bundle> @<project> [--dry-run] [--force] [--format=json]`** reuses the scanner + adds the pure `inc/reference-rewrite.js` (also fs/global-free): it moves `controller.<old>.js` → `controller.<new>.js`, moves `templates/html/<old>/`, and rewrites the old namespace at the two ANCHORED sites — routing.json `"namespace": "<old>"` VALUES (rule-level AND param.namespace; a QUOTED-STRING-anchored `replace`, NOT a JSON parse→stringify, so comments/ordering/whitespace survive byte-for-byte, and a substring like `checkout2` or a `:variable` value is never matched) and every `requireController('<old>')` literal (both quote styles, spacing preserved). Unlike `remove`, rename DOES edit routing.json (only those values). A full plan is shown, then an interactive readline confirm (non-TTY aborts naming `--force`); apply is ALL-OR-NOTHING — snapshot every write+move, roll back on any failure. `--force` applies without the prompt, `--dry-run` previews, `--format=json` emits an envelope and applies only with `--force`. Residuals it REPORTS-not-rewrites: `:variable`/non-literal dynamic refs and the cosmetic `<Bundle><Namespace>Controller` class name (gina loads by file path, so it is a label, not a reference). Target collision (`controller.<new>.js` or `templates/html/<new>/` exists) hard-refuses — no overwrite. Tests: `test/lib/controller-rename.test.js` (18).
|
|
993
993
|
|
|
994
994
|
276. **Worker-global proxy-context poisoning by port-less internal calls — the `getUrl`/`url` template filters, the cross-bundle redirect-by-URL target and the error-fallback redirect now prefer the emitting request's own classification; opt-in `server.proxy.requireForwardedHeaders` makes classification deterministic (#B152).** A request whose inbound Host carries no `:port` is classified reverse-proxied (the first arm of the per-request classification, both engines) and REFRESHES `process.gina.PROXY_HOST`/`PROXY_HOSTNAME` — but a port-less Host is also what an internal call addressed by service/DNS name carries (a container health probe on an app route — only `/_gina/health/check` itself, `$`-anchored, bypasses the classification block — a mesh hop, a sibling-bundle request), so ONE such call repointed every later worker-global read at the internal host: both `getUrl` filter branches (the path/bundle-override `hostname` composition AND the post-`getRoute` `proxy_hostname` override feeding `toUrl()`), the redirect-by-URL `getRoute(path).toUrl()` branch, and `throwError`'s route-object fallback. On a proxy-less fresh worker the same call CREATES proxy mode permanently (the composite latch arms once the global exists). Fixed server-side, NO dist rebuild (`getUrl` is not browser-bundled — the dist's `getUrl` hits are `getUrlProps`, a substring artifact): all four readers prefer THIS request's per-request slots (`req._ginaIsProxyHost` strict-`=== true` + `req._ginaProxyHostname`) over the worker-global, which stays the fallback for renders with no request of their own — a raw victim resolves the config host despite the latch, a proxied victim emits its own host, a slot-less caller is byte-identical; `core/router.js` fills the slots when ABSENT so the Express engine (which never set them) gets per-request truth engine-agnostically, isaac's earlier identical classification always winning. The opt-in key (settings.json + published schema; strict boolean, fail-safe false, boot-resolved once, `console.info` when armed) disables the port-less heuristic so ONLY X-Forwarded-Host classifies as proxied — the one mechanism that also protects req-less renders; enable it only behind a front proxy that always sends X-Forwarded-Host. Two mechanism corrections vs the field report that surfaced this: `PROXY_PORT` is boot-static (never request-refreshed; the boot scheme-switch forces it to 80/443, clobbering any proxy.json-hostname port), so a nonstandard port in an emitted URL comes from the victim request's OWN normalized `headers.port`/`[':port']`, never the poisoner; and moving container probes off `/_gina/health/check` onto app routes is what acquires the bug — nothing signals it. Pickup: restart (server-side only). Tests: `test/core/proxy-request-scope.test.js` (44, incl. a real `getRoute`/`toUrl` subtract reproducing the internal-host emission pre-fix).
|
|
995
|
-
277. **Render/output cache — pluggable backends, release-namespaced keys, event invalidation, flush, Cache-Status (consolidates former #234/#235/#237/#238/#242/#244; 0.5.18–0.5.22).** The framework caches rendered responses under two key namespaces — `static:` HTML + `data:` JSON — in the multi-purpose server Map (which ALSO holds `swig:` compiled templates + `http2session:` sessions: every bulk operation scopes to the output namespaces ONLY). CONFIG: bundle-wide defaults on `server.cache` (`enable` is the hard gate for writer AND reader; plus `path`/`ttl`/`sliding`/`maxAge`); `type`/`store` come from the bundle `config/settings.json` top-level `cache` block, folded into the runtime `server.cache` at config-load (env.json keys win; without the fold the documented default was inert); per-route via a routing.json rule's top-level `cache: {…}` with FILL-only inheritance — a per-route value always wins, and a route that sets `type` at all keeps it (only an OMITTED `type` inherits the bundle default). STRATEGIES: `memory` (inline content); `fs` (body file + a `.meta` sidecar carrying created/ttl/sliding/maxAge/headers/events; restart READ-BACK on an index miss with ABSOLUTE expiry preserved — a restart never extends a TTL; pure-sliding read-back counts as a fresh access, a documented imprecision); `redis` two-tier (L1 = the in-process Map written synchronously; L2 = shared redis via fire-and-forget `PSETEX` — the response never waits; `warm()` repopulates L1 with the AUTHORITATIVE remaining PTTL and re-registers the route's events so a warmed entry stays evictable; fail-open with one once-per-process warn + a 1s `commandTimeout` so a blackholed socket cannot hang the render hot path; a graceful shutdown leaves L2 INTACT — peer replicas and the restarting replica warm from it; every redis route needs a ttl or `invalidateOnEvents` — boot-enforced fail-fast, with proportionality: an `enable:false` bundle never opens a connection and would-be-fatals downgrade to loud warns). KEYS: one `buildKey` owns `[<token>:]<kind>:<bundle>:<url>` at every writer AND reader (the format was previously duplicated at 4 sites and drifted); the token (`GINA_CACHE_NAMESPACE || GINA_VERSION`, sanitized) release-namespaces every cache so a framework upgrade auto-invalidates, and the token is ALSO an fs PATH segment — a measured requirement, not cosmetics: with the token only in the key, a namespace change reused the same file path and read-back served stale cross-namespace bytes. EVENTS: routes register `cache.invalidateOnEvents`; fire from a controller via `self.cache.invalidateByEvent(event)` (a deliberately NARROW facade — it never exposes `from()`/`set()`, and reaches the OWN process only) or cross-bundle via `gina cache:clear @<project> --event=<name>` / `POST /_gina/cache/clear?event=<name>`; TTL/sliding expiry runs the SAME eviction as an explicit delete (cleanup fns fire + registrations reclaim), and fs/redis persistence re-registers events on read-back/warm. FLUSH: the CLI runs the offline fs reclaim FIRST (works with the bundle down; reclaims prior-release orphan dirs; never touches the reserved `config`/`swig` infra-cache dirs) then the in-heap endpoint (admin-gated, POST-only — a flush is a mutation a prefetch must not fire; `event` WINS over `bundle`); `--dry-run` previews the fs set + probes reachability read-only and deliberately claims NO count. READ PATH: engine-agnostic in the shared request handler (express included — previously isaac-only), so a fresh replica's FIRST GET can serve a peer replica's write; every hit carries RFC 9211 `Cache-Status: gina-cache; hit; ttl=N; detail=memory|redis|fs` (naming the physical tier that served the bytes) and every genuine miss `gina-cache; fwd=uri-miss`; cached routes re-mint CSP nonces on hits (#B130 — header + body, stored entries never mutated). Server-side only — none of this ever needs a dist rebuild. Tests: `test/lib/render-cache.test.js`, `test/core/server-render-cache-read.test.js`, `test/core/server-render-cache-boot.test.js`, `test/lib/cache-clear.test.js`; consumer guide: the docs-site caching guide.
|
|
995
|
+
277. **Render/output cache — pluggable backends, release-namespaced keys, event invalidation, flush, Cache-Status (consolidates former #234/#235/#237/#238/#242/#244; 0.5.18–0.5.22).** The framework caches rendered responses under two key namespaces — `static:` HTML + `data:` JSON — in the multi-purpose server Map (which ALSO holds `swig:` compiled templates + `http2session:` sessions: every bulk operation scopes to the output namespaces ONLY). CONFIG: bundle-wide defaults on `server.cache` (`enable` is the hard gate for writer AND reader; plus `path`/`ttl`/`sliding`/`maxAge`); `type`/`store` come from the bundle `config/settings.json` top-level `cache` block, folded into the runtime `server.cache` at config-load (env.json keys win; without the fold the documented default was inert); per-route via a routing.json rule's top-level `cache: {…}` with FILL-only inheritance — a per-route value always wins, and a route that sets `type` at all keeps it (only an OMITTED `type` inherits the bundle default). STRATEGIES: `memory` (inline content); `fs` (body file + a `.meta` sidecar carrying created/ttl/sliding/maxAge/headers/events; restart READ-BACK on an index miss with ABSOLUTE expiry preserved — a restart never extends a TTL; pure-sliding read-back counts as a fresh access, a documented imprecision); `redis` two-tier (L1 = the in-process Map written synchronously; L2 = shared redis via fire-and-forget `PSETEX` — the response never waits; `warm()` repopulates L1 with the AUTHORITATIVE remaining PTTL and re-registers the route's events so a warmed entry stays evictable; fail-open with one once-per-process warn + a 1s `commandTimeout` so a blackholed socket cannot hang the render hot path; a graceful shutdown leaves L2 INTACT — peer replicas and the restarting replica warm from it; every redis route needs a ttl or `invalidateOnEvents` — boot-enforced fail-fast, with proportionality: an `enable:false` bundle never opens a connection and would-be-fatals downgrade to loud warns). KEYS: one `buildKey` owns `[<token>:]<kind>:<bundle>:<url>` at every writer AND reader (the format was previously duplicated at 4 sites and drifted); the token (`GINA_CACHE_NAMESPACE || GINA_VERSION`, sanitized) release-namespaces every cache so a framework upgrade auto-invalidates, and the token is ALSO an fs PATH segment — a measured requirement, not cosmetics: with the token only in the key, a namespace change reused the same file path and read-back served stale cross-namespace bytes. EVENTS: routes register `cache.invalidateOnEvents`; fire from a controller via `self.cache.invalidateByEvent(event)` (a deliberately NARROW facade — it never exposes `from()`/`set()`, and reaches the OWN process only) or cross-bundle via `gina cache:clear @<project> --event=<name>` / `POST /_gina/cache/clear?event=<name>`; TTL/sliding expiry runs the SAME eviction as an explicit delete (cleanup fns fire + registrations reclaim), and fs/redis persistence re-registers events on read-back/warm. FLUSH: the CLI runs the offline fs reclaim FIRST (works with the bundle down; reclaims prior-release orphan dirs; never touches the reserved `config`/`swig` infra-cache dirs) then the in-heap endpoint (admin-gated, POST-only — a flush is a mutation a prefetch must not fire; `event` WINS over `bundle`); `--dry-run` previews the fs set + probes reachability read-only and deliberately claims NO count. READ PATH: engine-agnostic in the shared request handler (express included — previously isaac-only), so a fresh replica's FIRST GET can serve a peer replica's write; every hit carries RFC 9211 `Cache-Status: gina-cache; hit; ttl=N; detail=memory|redis|fs` (naming the physical tier that served the bytes) and every genuine miss `gina-cache; fwd=uri-miss`; cached routes re-mint CSP nonces on hits (#B130 — header + body, stored entries never mutated). **A gated route is never cached** — pairing `cache` with `param.requireAuth`/`roles`/`policy` (or leaving it mode-gated) REFUSES the boot, and the delegates skip the write regardless: the key carries no principal and both serve points precede the authorization gate (#B158). Server-side only — none of this ever needs a dist rebuild. Tests: `test/lib/render-cache.test.js`, `test/core/server-render-cache-read.test.js`, `test/core/server-render-cache-boot.test.js`, `test/lib/cache-clear.test.js`; consumer guide: the docs-site caching guide.
|
|
996
996
|
|
|
997
997
|
278. **A cache key is opaque DATA — never route it through an expression/condition evaluator.** An output-cache key embeds the request URL, so a querystring's `?`/`=` parse as OPERATOR tokens in any condition-DSL lookup — the render cache's event registry originally lived in a collection whose dedup ran keys through the condition evaluator, and the SECOND cache-miss render of any cached GET route with `invalidateOnEvents` + a querystring THREW (in the swig path that rejection unwound to the function-level try, whose catch answered 500 — discarding an already-rendered page). The registry became a plain array matched with `===`. Generalizes beyond caching: never let a value carrying user-controlled characters reach a query/condition DSL as an expression — match registry rows with `===` on plain structures, and treat every composite key as an opaque string.
|
|
998
998
|
|
|
999
|
-
279. **Transient-vs-permanent connector-error classification (#CE1, `26d803bd`+`d9231eff`, 0.5.25).** `lib/connector-error` (`classify(err) → {isTransient, reason}` + in-place `stamp(err)`) stamps `err.isTransient` (boolean; explicit `false` = classified-permanent, not merely absent) + `err.transientReason` (normalized token, `null` when permanent) on every datastore query error reaching the controller, so an app renders an honest retryable response by branching on the CONDITION instead of string-matching vendor text. Wired at 2 error sites per connector (Promise reject + direct-callback) across couchbase/mongodb/mysql/postgresql/scylladb/sqlite; `stamp()` RETURNS err so the call FOLDS into the terminal (`_reject(lib.connectorError.stamp(err))`) — the two-line form pushes `_queryEntry.resultSize` past inspector.test.js's fixed-width QI `substring(idx,idx+1800/900)` windows (thin post-fix margins 12/22 — RE-MEASURE on any connector error-branch edit; same fragility class as the #B152 260-char window). Taxonomy, first-match-wins IN ORDER: socket errno (ECONNREFUSED/ECONNRESET/ETIMEDOUT/EPIPE/EHOSTUNREACH/ENETUNREACH/ENETDOWN/EAI_AGAIN transient; **ENOTFOUND EXCLUDED** = DNS misconfig, not a blip) → mysql/sqlite string codes → **node:sqlite NUMERIC `errcode` primary byte** (MEASURED: a busy error is `code:'ERR_SQLITE_ERROR'`+`errcode:5`, NEVER `code:'SQLITE_BUSY'`; `errcode & 0xff` → 5 busy / 6 locked, so extended 261 SQLITE_BUSY_RECOVERY→5; dup-key 1555→19 stays permanent) → pg SQLSTATE (exact set + whole `08` connection class, 5-char-gated) → driver class NAMES (cassandra `NoHostAvailableError`/`OperationTimedOutError`, couchbase `*TimeoutError`/`RequestCanceledError`/`ServiceNotAvailableError`, mongo `MongoNetworkError`/`*SelectionError`) → mongo error LABELS (`TransientTransactionError`/`RetryableWriteError`) → mongo numeric codes (**7 HostNotFound EXCLUDED** = server-side ENOTFOUND; 6 HostUnreachable kept) → couchbase N1QL `cause.first_error_code` 1080 + 12008 bulk-get-retry-exhaustion + `cause.retry===true` (**12009 generic-DML EXCLUDED** = also covers dup-key; the SDK buckets every un-cased 12xxx — permanent 12003 included — into one IndexFailureError grab-bag, so the cause CODE is the signal and that class name must never join the name table; the #B153 envelope-forward reaches classify as a synthesized name-`Error` wrapper, making the code table the SOLE classifier on
|
|
999
|
+
279. **Transient-vs-permanent connector-error classification (#CE1, `26d803bd`+`d9231eff`, 0.5.25).** `lib/connector-error` (`classify(err) → {isTransient, reason}` + in-place `stamp(err)`) stamps `err.isTransient` (boolean; explicit `false` = classified-permanent, not merely absent) + `err.transientReason` (normalized token, `null` when permanent) on every datastore query error reaching the controller, so an app renders an honest retryable response by branching on the CONDITION instead of string-matching vendor text. Wired at 2 error sites per connector (Promise reject + direct-callback) across couchbase/mongodb/mysql/postgresql/scylladb/sqlite; `stamp()` RETURNS err so the call FOLDS into the terminal (`_reject(lib.connectorError.stamp(err))`) — the two-line form pushes `_queryEntry.resultSize` past inspector.test.js's fixed-width QI `substring(idx,idx+1800/900)` windows (thin post-fix margins 12/22 — RE-MEASURE on any connector error-branch edit; same fragility class as the #B152 260-char window). Taxonomy, first-match-wins IN ORDER: socket errno (ECONNREFUSED/ECONNRESET/ETIMEDOUT/EPIPE/EHOSTUNREACH/ENETUNREACH/ENETDOWN/EAI_AGAIN transient; **ENOTFOUND EXCLUDED** = DNS misconfig, not a blip) → mysql/sqlite string codes → **node:sqlite NUMERIC `errcode` primary byte** (MEASURED: a busy error is `code:'ERR_SQLITE_ERROR'`+`errcode:5`, NEVER `code:'SQLITE_BUSY'`; `errcode & 0xff` → 5 busy / 6 locked, so extended 261 SQLITE_BUSY_RECOVERY→5; dup-key 1555→19 stays permanent) → pg SQLSTATE (exact set + whole `08` connection class, 5-char-gated) → driver class NAMES (cassandra `NoHostAvailableError`/`OperationTimedOutError`, couchbase `*TimeoutError`/`RequestCanceledError`/`ServiceNotAvailableError`, mongo `MongoNetworkError`/`*SelectionError`) → mongo error LABELS (`TransientTransactionError`/`RetryableWriteError`) → mongo numeric codes (**7 HostNotFound EXCLUDED** = server-side ENOTFOUND; 6 HostUnreachable kept) → couchbase N1QL `cause.first_error_code` 1080 + 12008 bulk-get-retry-exhaustion + `cause.retry===true` (**12009 generic-DML EXCLUDED** = also covers dup-key; the SDK buckets every un-cased 12xxx — permanent 12003 included — into one IndexFailureError grab-bag, so the cause CODE is the signal and that class name must never join the name table; the #B153 envelope-forward reaches classify as a synthesized name-`Error` wrapper WHENEVER THE ENVELOPE CARRIES TEXT, making the code table the SOLE classifier on that path — the 1080 entry is live there, dead only on the raw-SDK shape where the typed timeout name fires first). **#B153 RESIDUAL (fixed 0.5.26)** — the synthesize branch was gated on `typeof(cause.first_error_message) != 'undefined'`, but the node binding marshals `first_error_code`/`first_error_message` onto EVERY query error (the C++ `query_error_context` value-initializes them), so a CLIENT-side SDK timeout — `cause` present, code `0`, message `''` — took the synthesize branch and became `new Error('')`, destroying the typed `Un/AmbiguousTimeoutError` name `classify` matches on, and a retryable timeout was stamped PERMANENT with message `''`. Guard gains `&& cause.first_error_message !== ''` at all three couchbase N1QL `onError` sites, so an empty envelope raw-forwards instead: raw-forwarding is classification-LOSSLESS (the raw error keeps `.cause`, so even a pathological empty-message SERVER envelope still classifies off the code table — the synthesize branch only ever existed to surface envelope text). Named residual: a NON-Error rejection carrying an empty message still loses `.cause` on the `new Error(String(err))` wrap — no known producer (the SDK rejects with typed Errors, and the empty-message case IS the typed timeout). Server-side — NO dist rebuild; restart to pick up. Tests: `couchbase-connector.test.js §08` (14 — source pins on the new clause + client-timeout end-to-end replicas asserting the typed name survives and `classify().isTransient === true`, plus a pre-residual subtract control reproducing the false negative). `classify` is TOTAL — never throws (invoked on the error path; hostile shapes → permanent); `stamp` is frozen-safe. Registered PLAIN `require` (gen-0-captured by the load-once connectors + invoked per-request → a `_require` copy would be a #B32-residual leak candidate). Couchbase is classifiable ONLY because #B153 (`3ac5ea4a`) forwards the RAW driver error its old `.catch` used to discard (and used to HANG on when there was no `cause`). Declared on `GinaLib` in `types/index.d.ts` (the types-runtime-parity two-way gate). Deferred: slice 2 (opt-in 503 + `Retry-After`), slice 3 (opt-in single auto-retry keyed on the entity OPERATION, not the serving request's HTTP verb — a GET can issue mutating queries). Server-side — NO dist rebuild; restart to pick up. Tests: `test/core/couchbase-connector.test.js §08` (#B153) + `test/lib/connector-error.test.js` (71).
|
|
1000
|
+
280. **Framework control-plane bind host + command-name namespace (0.5.26).** The two control-plane listeners — the command socket (default `8124`, `bin/cmd`, which executes a CLI command per connection) and the MQ listener (default `8125`, `lib/logger/src/containers/mq/listener.js`) — bind an explicit host that defaults to loopback. The `bind_host` setting governs it (env `GINA_BIND_HOST`, flag `gina framework:set --bind-host=`, seeded into `~/.gina/<shortVersion>/settings.json` and carried across shortVersion bumps by the `checkIfSettings` migration map); it is deliberately SEPARATE from `host_v4`, which is the address clients CONNECT to — reusing one key for both would make a workstation whose `host_v4` points at another machine fail to bind its own daemon (EADDRNOTAVAIL). Node binds every interface when `listen()` gets no host argument, and the MQ listener reads `opt.hostV4` specifically, so a caller passing a `host` key leaves it undefined and binds everything — both now default to `127.0.0.1` at the listener itself as well as at the resolution site. Exposing the control plane beyond the local host is a deliberate opt-in, mirroring a bundle's `--http-host`. Separately, `lib/cmd/framework/init.js` `run()` constrains a caller-supplied `topic:action` pair to `/^[A-Za-z0-9_-]+$/` before it becomes a `require()` path (an out-of-namespace segment resolves to `''`, which never exists, so it takes the same "not a valid command" branch); every shipped command group and action matches, including the synthetic `framework:-V` / `framework:--version` forms. An unresolvable name reaching the daemon over the socket ends that client's connection instead of calling `process.exit(1)`, which would stop the daemon serving every other client — an offline one-shot CLI run still exits non-zero. NOTE most command handlers call `process.exit()` themselves, so only `bundle:start` (the sole command `bin/cli` routes online) is designed to run inside the daemon.
|
|
1001
|
+
|
|
1002
|
+
281. **Production transport posture — `server.requireHttps` / `server.allowInsecure` (#COMPLY9, 0.5.26).** Outside the `local` scope a bundle resolving a cleartext scheme (anything but https — both engines' scheme switches default to the plain server) warns ONCE at boot, naming bundle/scheme/scope and both remediations; `server.requireHttps: true` refuses to boot it instead (the throw lands in init()'s central catch — pre-listen, the cleartext port never binds), and `server.allowInsecure: true` asserts TLS terminates upstream (mesh/ingress/reverse proxy — the documented h2c topology), turning the warn into one info line (same vocabulary as `mcp.json > server > allowInsecure`). Both strict booleans resolved like `scheme` itself (bundle settings win, env.json's `server` block fills via the serverOpt picked-keys merge); a non-boolean-when-present and the both-true contradiction refuse the boot in EVERY scope (the quietly-OFF class). The gate is NOT-local, never is-production — a custom scope (e.g. `beta`) is neither, and a production-keyed gate would silently skip it; `conf.server.scopeIsLocal` derives from def_scope, not the live scope, so it is never consulted. An https:// proxy.json upstream hostname is NAMED in the warn (advisory) but never silences it. Server-side only — no dist rebuild; pickup = restart.
|
|
1003
|
+
|
|
1004
|
+
282. **Couchbase `.sql` `@options` annotation — the exact contract, and the consistency gate that silently dropped keys (#B155; warns since 0.5.26).** The parser accepts ONLY `@options { … }` — a brace-delimited JS-object-literal after exactly ONE space (unquoted keys fine: a key-quoting normalisation runs before `JSON.parse`; a malformed body warns and is skipped). The historical docs-taught brace-less form (`@options consistency=request_plus`) and a double-space-before-brace both MISS the parse regex entirely. The passthrough into the SDK's query options is GATED on the `consistency` key: any other key (`adhoc`, `timeout`, `profile`, …) applies ONLY when `consistency` is present alongside it — alone it is parsed then dropped. Since 0.5.26 BOTH failure shapes warn (was silent): an unparseable `@options` mention warns with the exact working form; a gate-shut drop warns naming the ignored keys + the `"consistency": "not_bounded"` remedy; an empty `@options {}` drops nothing and stays quiet. An UNKNOWN consistency VALUE warns and falls back to `not_bounded` but STILL opens the gate — the gate keys on presence, not validity. Defaults on the query path: `adhoc: false` (statement plans cached — `true` disables that) + `not_bounded`; user keys WIN over framework values (direct assignment — including dev-mode's `profile: 'timings'`). `bulkInsert` is a SEPARATE surface: a JS `options` argument, UNGATED, merged caller-wins-on-conflict / defaults-fill-missing (its default is `adhoc: true`). The gate itself deliberately stays: un-gating would make historically-inert options suddenly live for every consumer, and a bare un-gate CRASHES (the next statement dereferences `options.consistency`) — a restructure gated on field evidence, which the new warns now collect. Tests: `test/core/couchbase-connector.test.js §09` drives the SHIPPED parse+gate bytes (unique-text-anchored slices — line numbers rot and the parse block's regex holds an unbalanced `{` that defeats brace-matching).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gina",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.26",
|
|
4
4
|
"description": "MVC framework for Node.js and Bun with built-in HTTP/2, multi-bundle architecture, and scope-based data isolation — no Express dependency",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nodejs",
|
|
@@ -76,12 +76,12 @@
|
|
|
76
76
|
"gina-container": "bin/gina-container",
|
|
77
77
|
"gina-init": "bin/gina-init"
|
|
78
78
|
},
|
|
79
|
-
"main": "./framework/v0.5.
|
|
79
|
+
"main": "./framework/v0.5.26/core/gna",
|
|
80
80
|
"exports": {
|
|
81
81
|
".": {
|
|
82
82
|
"types": "./types/index.d.ts",
|
|
83
83
|
"import": "./index.mjs",
|
|
84
|
-
"require": "./framework/v0.5.
|
|
84
|
+
"require": "./framework/v0.5.26/core/gna.js"
|
|
85
85
|
},
|
|
86
86
|
"./gna": {
|
|
87
87
|
"types": "./types/gna.d.ts",
|
package/schema/routing.json
CHANGED
|
@@ -68,6 +68,26 @@
|
|
|
68
68
|
"isPopinContext": {
|
|
69
69
|
"type": "boolean",
|
|
70
70
|
"description": "Set to true for routes rendered inside a popin overlay."
|
|
71
|
+
},
|
|
72
|
+
"requireAuth": {
|
|
73
|
+
"type": "boolean",
|
|
74
|
+
"description": "Require an authenticated session (#COMPLY1). STRICTLY boolean — any other type refuses to boot, because a truthy string would NOT gate the route. An unauthenticated caller gets a 401, or a 302 to auth.loginRoute for a browser navigation. Cannot be combined with a route-level `cache` block (the cache is read before the gate and its key carries no user identity), nor declared on a method:\"ws\" route (a handshake never reaches the gate — authenticate in the wsHandler)."
|
|
75
|
+
},
|
|
76
|
+
"roles": {
|
|
77
|
+
"type": "array",
|
|
78
|
+
"minItems": 1,
|
|
79
|
+
"items": { "type": "string", "minLength": 1 },
|
|
80
|
+
"description": "Restrict the route to callers holding ANY of these roles. IMPLIES requireAuth — an unauthenticated caller can hold no role, so authentication is checked first and a denial is a 401 before it can be a 403. Strictly a non-empty array of non-empty strings; every other declared shape refuses to boot rather than half-gating the route.",
|
|
81
|
+
"examples": [["admin"], ["admin", "editor"]]
|
|
82
|
+
},
|
|
83
|
+
"policy": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"minLength": 1,
|
|
86
|
+
"description": "Name of a `policies/<name>.js` module in the bundle, exporting a SYNCHRONOUS function (user, req) that returns a literal true to allow. IMPLIES requireAuth, and is AND-composed after roles. Registered at boot: a missing, non-function or async module refuses to start rather than denying its route on every request."
|
|
87
|
+
},
|
|
88
|
+
"public": {
|
|
89
|
+
"type": "boolean",
|
|
90
|
+
"description": "Exempt this route from auth.requireAuthByDefault (#COMPLY10). STRICTLY boolean — a truthy string would NOT exempt it. Meaningful only while the deny-by-default mode is on; declaring it alongside requireAuth / roles / policy is a boot-refused contradiction, since a route cannot be both exempt from authentication and gated by it."
|
|
71
91
|
}
|
|
72
92
|
}
|
|
73
93
|
},
|
package/schema/settings.json
CHANGED
|
@@ -67,6 +67,11 @@
|
|
|
67
67
|
"description": "Authentication & authorization gate settings (#COMPLY1 route authorization + #MS3 machine-caller authentication). Boot config: changes need a bundle restart. Route-level gating itself is declared in routing.json (param.requireAuth / param.roles / param.policy).",
|
|
68
68
|
"additionalProperties": false,
|
|
69
69
|
"properties": {
|
|
70
|
+
"requireAuthByDefault": {
|
|
71
|
+
"type": "boolean",
|
|
72
|
+
"description": "Deny-by-default authorization (#COMPLY10) — STRICTLY boolean (any other type refuses to boot: a truthy string would leave every un-annotated route silently UNGATED). When true, every route in this bundle requires an authenticated session unless its routing.json param block carries \"public\": true. Routes already declaring requireAuth / roles / policy are unaffected, and \"public\" can never un-gate one of those. Recorded PER BUNDLE, so enabling it in one bundle never changes a sibling's posture in merged mode. Fail-closed default: false.",
|
|
73
|
+
"default": false
|
|
74
|
+
},
|
|
70
75
|
"loginRoute": {
|
|
71
76
|
"type": ["string", "null"],
|
|
72
77
|
"description": "Login bounce target for unauthenticated BROWSER navigations on gated routes: a routing.json rule name (recommended), or an absolute path like \"/login\". null (default) disables the bounce — every unauthenticated request to a gated route gets a 401. XHR requests always get the 401, never a redirect. The bounce is always a non-cacheable 302.",
|
|
@@ -133,6 +138,14 @@
|
|
|
133
138
|
"description": "URL scheme. Use \"https\" for HTTP/2 (required) or \"http\" for HTTP/1.1 only.",
|
|
134
139
|
"enum": ["https", "http"]
|
|
135
140
|
},
|
|
141
|
+
"requireHttps": {
|
|
142
|
+
"type": "boolean",
|
|
143
|
+
"description": "Opt-in transport enforcement. When true, a bundle resolving a cleartext scheme (anything but \"https\") outside the local scope REFUSES to boot — pre-listen, so the cleartext port is never reachable. Inert in the local scope. Setting it together with allowInsecure is a boot-refused contradiction. Defaults to false: a cleartext bundle outside the local scope warns at boot instead."
|
|
144
|
+
},
|
|
145
|
+
"allowInsecure": {
|
|
146
|
+
"type": "boolean",
|
|
147
|
+
"description": "The operator's assertion that TLS terminates upstream (service mesh, ingress/load balancer, reverse proxy — the documented h2c topology). When true, the boot-time cleartext-transport warning outside the local scope becomes a single info line. Same vocabulary as mcp.json > server > allowInsecure. Setting it together with requireHttps is a boot-refused contradiction. Defaults to false."
|
|
148
|
+
},
|
|
136
149
|
"allowHTTP1": {
|
|
137
150
|
"type": "boolean",
|
|
138
151
|
"description": "When true, the HTTP/2 server also accepts HTTP/1.1 connections (ALPN negotiation). Defaults to true."
|
package/utils/helper.js
CHANGED
|
@@ -110,7 +110,7 @@ function MainHelper(opt) {
|
|
|
110
110
|
// (e.g. port:set reads --port itself). Framework-scoped commands
|
|
111
111
|
// still hoist them (so `gina start --port=N` / `framework:set
|
|
112
112
|
// --port=N` persist to settings.json as intended).
|
|
113
|
-
if ( !_isFrameworkScopedCmd && /^\-\-(port|mq-port|host-v4|hostname|debug-port|debug_port)=/.test(process.argv[a]) ) {
|
|
113
|
+
if ( !_isFrameworkScopedCmd && /^\-\-(port|mq-port|host-v4|bind-host|bind_host|hostname|debug-port|debug_port)=/.test(process.argv[a]) ) {
|
|
114
114
|
newArgv[a] = process.argv[a];
|
|
115
115
|
continue;
|
|
116
116
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.5.25
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.css
RENAMED
|
File without changes
|
/package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.js
RENAMED
|
File without changes
|
/package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/beemaster/index.html
RENAMED
|
File without changes
|
|
File without changes
|
/package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.br
RENAMED
|
File without changes
|
/package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.gz
RENAMED
|
File without changes
|
/package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/html/statusbar.html
RENAMED
|
File without changes
|
/package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.br
RENAMED
|
File without changes
|
/package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.gz
RENAMED
|
File without changes
|
|
File without changes
|
/package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/inspector/index.html
RENAMED
|
File without changes
|
/package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/inspector/inspector.css
RENAMED
|
File without changes
|
/package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/inspector/inspector.js
RENAMED
|
File without changes
|
/package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/inspector/logo.svg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js
RENAMED
|
File without changes
|
/package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.br
RENAMED
|
File without changes
|
/package/framework/{v0.5.25 → v0.5.26}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.gz
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/framework/{v0.5.25 → v0.5.26}/core/plugins/lib/security-headers/hide-powered-by/README.md
RENAMED
|
File without changes
|