gina 0.5.3 → 0.5.4
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 +24 -0
- package/README.md +11 -9
- package/ROADMAP.md +1 -0
- package/framework/v0.5.4/VERSION +1 -0
- package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/html/statusbar.html +40 -1
- package/framework/v0.5.4/core/asset/plugin/dist/vendor/gina/html/statusbar.html.br +0 -0
- package/framework/v0.5.4/core/asset/plugin/dist/vendor/gina/html/statusbar.html.gz +0 -0
- package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/inspector/inspector.js +180 -100
- package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/js/gina.js +91 -15
- package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/js/gina.min.js +216 -215
- package/framework/v0.5.4/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
- package/framework/v0.5.4/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
- package/framework/{v0.5.3 → v0.5.4}/core/controller/controller.js +26 -0
- package/framework/{v0.5.3 → v0.5.4}/core/controller/controller.render-swig.js +15 -7
- package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/validator/src/form-validator.js +73 -13
- package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/validator/src/main.js +6 -1
- package/framework/{v0.5.3 → v0.5.4}/core/router.js +15 -2
- package/framework/{v0.5.3 → v0.5.4}/core/server.isaac.js +2 -38
- package/framework/{v0.5.3 → v0.5.4}/core/server.js +195 -30
- package/framework/{v0.5.3 → v0.5.4}/core/template/conf/settings.json +1 -1
- package/framework/v0.5.4/lib/admin/package.json +17 -0
- package/framework/v0.5.4/lib/admin/src/main.js +93 -0
- package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/add.js +38 -2
- package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/arguments.json +1 -0
- package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/help.txt +15 -1
- package/framework/{v0.5.3 → v0.5.4}/lib/index.js +27 -5
- package/framework/{v0.5.3 → v0.5.4}/lib/routing/src/main.js +12 -1
- package/framework/{v0.5.3 → v0.5.4}/package.json +1 -1
- package/gna.js +4 -4
- package/llms.txt +27 -1
- package/package.json +4 -4
- package/framework/v0.5.3/VERSION +0 -1
- package/framework/v0.5.3/core/asset/plugin/dist/vendor/gina/html/statusbar.html.br +0 -0
- package/framework/v0.5.3/core/asset/plugin/dist/vendor/gina/html/statusbar.html.gz +0 -0
- package/framework/v0.5.3/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
- package/framework/v0.5.3/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/AUTHORS +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/LICENSE +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/html/nolayout.html +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/html/static.html +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/img/android-chrome-192x192.png +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/img/android-chrome-512x512.png +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/img/apple-touch-icon.png +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/img/favicon-16x16.png +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/img/favicon-32x32.png +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/img/favicon.ico +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.css +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/beemaster/index.html +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/css/gina.min.css +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.br +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.gz +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/inspector/have_heart_one-webfont.woff2 +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/inspector/index.html +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/inspector/inspector.css +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/inspector/logo.svg +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.br +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.gz +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/config.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/ai/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/ai/lib/connector.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/couchbase/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/couchbase/lib/connector.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/couchbase/lib/connector.v3.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/couchbase/lib/connector.v4.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/couchbase/lib/n1ql.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/couchbase/lib/session-store.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/couchbase/lib/session-store.v3.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/couchbase/lib/session-store.v4.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/mongodb/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/mongodb/lib/connector.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/mongodb/lib/pipeline-loader.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/mongodb/lib/session-store.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/mysql/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/mysql/lib/connector.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/postgresql/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/postgresql/lib/connector.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/redis/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/redis/lib/session-store.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/scylladb/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/scylladb/lib/connector.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/scylladb/lib/session-store.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/sql-parser.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/sqlite/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/sqlite/lib/connector.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/connectors/sqlite/lib/session-store.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/content.encoding +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/controller/controller.framework.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/controller/controller.render-json.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/controller/controller.render-nunjucks-async.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/controller/controller.render-nunjucks.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/controller/controller.render-stream.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/controller/controller.render-swig-async.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/controller/controller.render-v1.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/controller/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/controller/inspector-window-emit.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/deps/busboy-1.6.0/LICENSE +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/deps/busboy-1.6.0/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/deps/busboy-1.6.0/lib/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/deps/busboy-1.6.0/lib/types/multipart.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/deps/busboy-1.6.0/lib/types/urlencoded.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/deps/busboy-1.6.0/lib/utils.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/deps/busboy-1.6.0/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/deps/streamsearch-1.1.0/LICENSE +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/deps/streamsearch-1.1.0/lib/sbmh.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/deps/streamsearch-1.1.0/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/dev/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/dev/lib/class.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/dev/lib/factory.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/dev/lib/tools.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/gna.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/locales/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/locales/currency.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/locales/dist/language/en.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/locales/dist/language/fr.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/locales/dist/region/en.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/locales/dist/region/fr.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/locales/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/mime.types +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/model/entity.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/model/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/model/template/entityFactory.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/model/template/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/csrf/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/csrf/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/csrf/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/coep/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/coep/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/coep/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/coop/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/coop/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/coop/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/corp/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/corp/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/corp/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/csp/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/csp/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/csp/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/hide-powered-by/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/hide-powered-by/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/hide-powered-by/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/hsts/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/hsts/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/hsts/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/origin-agent-cluster/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/origin-agent-cluster/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/origin-agent-cluster/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/referrer-policy/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/referrer-policy/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/referrer-policy/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-content-type-options/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-content-type-options/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-content-type-options/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-dns-prefetch-control/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-dns-prefetch-control/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-dns-prefetch-control/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-download-options/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-download-options/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-download-options/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-frame-options/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-frame-options/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-frame-options/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-xss-protection/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-xss-protection/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/security-headers/x-xss-protection/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/session/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/session/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/session/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/storage/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/storage/build.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/storage/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/storage/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/validator/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/validator/build.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/plugins/lib/validator/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/server.express.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/status.codes +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/_gitignore +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle/config/app.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle/config/connectors.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle/config/routing.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle/config/settings.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle/config/settings.server.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle/config/templates.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle/config/watchers.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle/controllers/controller.content.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle/controllers/controller.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle/controllers/setup.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle/locales/en.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle_namespace/controllers/controller.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle_public/css/default.css +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle_public/css/home.css +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle_public/css/vendor/readme.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle_public/favicon.ico +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle_public/js/vendor/readme.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle_public/manifest.webmanifest +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle_public/readme.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle_public/sw.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle_templates/handlers/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle_templates/html/content/homepage.html +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle_templates/html/includes/error-msg-noscript.html +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle_templates/html/includes/error-msg-outdated-browser.html +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/boilerplate/bundle_templates/html/layouts/main.html +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/command/gina.bat.tpl +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/command/gina.tpl +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/conf/env.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/conf/manifest.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/conf/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/conf/statics.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/conf/templates.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/error/client/json/401.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/error/client/json/403.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/error/client/json/404.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/error/server/html/50x.html +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/error/server/json/500.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/error/server/json/503.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/core/template/extensions/logger/config.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/console.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/context.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/data/LICENSE +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/data/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/data/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/data/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/dateFormat.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/json/LICENSE +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/json/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/json/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/json/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/path.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/plugins/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/plugins/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/plugins/src/api-error.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/plugins/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/prototypes.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/task.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/helpers/text.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/archiver/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/archiver/build.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/archiver/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/archiver/src/dep/jszip.min.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/archiver/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/async/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/async/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cache/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cache/build.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cache/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cache/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/aliases.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/build.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/copy.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/cp.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/help.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/inc/name-rewrite.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/list.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/mcp-start.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/mcp.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/oas.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/openapi.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/remove.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/rename.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/restart.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/rm.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/start.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/status.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/bundle/stop.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/cache/stats.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/connector/add.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/connector/arguments.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/connector/help.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/connector/help.txt +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/connector/list.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/connector/migrate.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/connector/remove.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/connector/rm.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/env/add.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/env/get.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/env/help.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/env/help.txt +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/env/link-dev.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/env/list.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/env/remove.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/env/rm.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/env/set.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/env/unset.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/env/use.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/arguments.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/build.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/dot.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/get.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/help.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/help.txt +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/init.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/link-node-modules.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/link.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/msg.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/open.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/restart.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/set.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/start.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/status.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/stop.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/tail.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/update.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/framework/version.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/gina-dev.1.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/gina-framework.1.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/gina.1.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/helper.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/i18n/add.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/i18n/arguments.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/i18n/export.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/i18n/help.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/i18n/help.txt +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/i18n/import.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/i18n/scan.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/inspector/help.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/inspector/help.txt +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/inspector/open.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/minion/arguments.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/minion/help.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/minion/help.txt +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/minion/kill.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/minion/list.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/msg.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/port/help.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/port/help.txt +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/port/inc/scan.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/port/list.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/port/reset.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/port/set.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/project/add.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/project/arguments.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/project/build.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/project/help.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/project/help.txt +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/project/import.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/project/list.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/project/move.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/project/remove.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/project/rename.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/project/restart.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/project/rm.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/project/start.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/project/status.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/project/stop.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/protocol/arguments.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/protocol/help.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/protocol/help.txt +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/protocol/list.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/protocol/remove.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/protocol/set.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/scope/add.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/scope/help.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/scope/help.txt +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/scope/link-local.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/scope/link-production.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/scope/list.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/scope/remove.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/scope/rm.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/scope/use.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/secrets/arguments.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/secrets/check.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/secrets/help.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/secrets/help.txt +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/secrets/scan.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/service/help.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/service/help.txt +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/service/list.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/service/start.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd/view/add.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd-status-format/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cmd-status-format/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/collection/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/collection/build.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/collection/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/collection/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/config.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/connector-registry/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/connector-registry/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cron/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cron/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/cron/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/domain/LICENSE +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/domain/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/domain/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/domain/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/generator/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/i18n/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/i18n/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/inherits/LICENSE +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/inherits/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/inherits/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/inherits/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/inspector-redact/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/inspector-redact/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/instrument/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/instrument/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/job/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/job/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/logger/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/logger/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/logger/src/containers/default/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/logger/src/containers/file/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/logger/src/containers/file/lib/logrotator/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/logger/src/containers/file/lib/logrotator/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/logger/src/containers/mq/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/logger/src/containers/mq/listener.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/logger/src/containers/mq/speaker.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/logger/src/helper.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/logger/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/math/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/mcp-dispatch/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/mcp-dispatch/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/mcp-http/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/mcp-http/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/mcp-server/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/mcp-server/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/merge/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/merge/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/merge/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/metrics/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/metrics/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/model.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/nunjucks-filters/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/nunjucks-filters/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/nunjucks-filters/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/nunjucks-resolver/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/nunjucks-resolver/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/proc.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/routing/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/routing/build.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/routing/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/routing/src/radix.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/routing-introspect/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/routing-introspect/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/secrets/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/secrets/src/backends/env.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/secrets/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/session-store.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/shell.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/state.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/swig-filters/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/swig-filters/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/swig-filters/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/swig-resolver/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/swig-resolver/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/template-loaders/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/template-loaders/src/loaders/http.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/template-loaders/src/loaders/memory.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/template-loaders/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/url/README.md +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/url/index.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/url/routing.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/uuid/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/uuid/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/validator.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/watcher/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/watcher/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/ws-framing/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/ws-framing/src/main.js +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/ws-session/package.json +0 -0
- /package/framework/{v0.5.3 → v0.5.4}/lib/ws-session/src/main.js +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the gina package.
|
|
3
|
+
* Copyright (c) 2009-2026 Rhinostone <contact@gina.io>
|
|
4
|
+
*
|
|
5
|
+
* For the full copyright and license information, please view the LICENSE
|
|
6
|
+
* file that was distributed with this source code.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @module gina/lib/admin
|
|
11
|
+
*
|
|
12
|
+
* Admin /_gina/* IP-allowlist gate (#S7). Single source of truth for the
|
|
13
|
+
* access check on the admin-grade /_gina/* endpoints (`/_gina/info`,
|
|
14
|
+
* `/_gina/cache/stats`). Both server engines (`server.js` and
|
|
15
|
+
* `server.isaac.js`) previously carried a byte-identical copy of this
|
|
16
|
+
* helper; this module is now the single source and both engines call
|
|
17
|
+
* `lib.admin.isClientAllowed(req)`.
|
|
18
|
+
*
|
|
19
|
+
* The allowlist is resolved from `process.gina._adminAllowList`, which
|
|
20
|
+
* `gna.js` populates at bundle init from `app.json` `admin.allowFrom`
|
|
21
|
+
* (defaults to loopback `['127.0.0.1', '::1']`). Sibling of
|
|
22
|
+
* `lib.metrics.isClientAllowed` on a separate axis — admin endpoints expose
|
|
23
|
+
* process state (memory, uptime, HTTP/2 session counters, cache contents)
|
|
24
|
+
* and are gated separately from Prometheus scrapes.
|
|
25
|
+
*
|
|
26
|
+
* Registered as a PLAIN `require` in `lib/index.js` (not `_require`): a
|
|
27
|
+
* stateless pure-function leaf with no instance/singleton state to
|
|
28
|
+
* hot-reload — same #B32-residual precedent as merge / uuid / Collection.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* // from an engine handler (lib is the framework lib registry)
|
|
32
|
+
* if (!lib.admin.isClientAllowed(request)) {
|
|
33
|
+
* response.statusCode = 403;
|
|
34
|
+
* return response.end(JSON.stringify({ error: 'forbidden' }));
|
|
35
|
+
* }
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Default allowlist used when `admin.allowFrom` is unset — loopback only.
|
|
40
|
+
* @constant {string[]}
|
|
41
|
+
*/
|
|
42
|
+
var DEFAULT_ALLOW_LIST = ['127.0.0.1', '::1'];
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Decide whether a request's client IP is in an explicit allowlist. Inner
|
|
46
|
+
* seam exposed for branch testing without mutating `process.gina` state.
|
|
47
|
+
*
|
|
48
|
+
* Reads the client IP from `req.socket.remoteAddress` only — never trusts
|
|
49
|
+
* `X-Forwarded-For` (reverse proxies could spoof it). Normalises
|
|
50
|
+
* `::ffff:IPv4` (IPv6-mapped IPv4) → `IPv4` so listing `127.0.0.1` matches
|
|
51
|
+
* both forms. An empty list (`[]`) denies everyone (explicit lockdown).
|
|
52
|
+
*
|
|
53
|
+
* @inner
|
|
54
|
+
* @param {http.IncomingMessage|http2.Http2ServerRequest} req
|
|
55
|
+
* @param {string[]} list the allowlist to test against
|
|
56
|
+
* @returns {boolean} true if the client IP is in `list`
|
|
57
|
+
* @example
|
|
58
|
+
* _isAllowedWithList({ socket: { remoteAddress: '127.0.0.1' } }, ['127.0.0.1']); // true
|
|
59
|
+
* _isAllowedWithList({ socket: { remoteAddress: '10.0.0.1' } }, []); // false
|
|
60
|
+
*/
|
|
61
|
+
function _isAllowedWithList(req, list) {
|
|
62
|
+
if (list.length === 0) return false;
|
|
63
|
+
var ip = (req.socket && req.socket.remoteAddress)
|
|
64
|
+
|| (req.connection && req.connection.remoteAddress)
|
|
65
|
+
|| '';
|
|
66
|
+
if (ip.indexOf('::ffff:') === 0) ip = ip.slice(7);
|
|
67
|
+
return list.indexOf(ip) >= 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* IP-allowlist check for the admin-grade /_gina/* endpoints.
|
|
72
|
+
*
|
|
73
|
+
* Resolves the allowlist from `process.gina._adminAllowList` (set by
|
|
74
|
+
* `gna.js` from `app.json` admin.allowFrom), falling back to loopback-only
|
|
75
|
+
* when the global is missing (init not yet fired — the safest default).
|
|
76
|
+
*
|
|
77
|
+
* @param {http.IncomingMessage|http2.Http2ServerRequest} req
|
|
78
|
+
* @returns {boolean} true if the client IP is allowed, false otherwise
|
|
79
|
+
* @example
|
|
80
|
+
* if (!lib.admin.isClientAllowed(request)) { return self.throwError(403); }
|
|
81
|
+
*/
|
|
82
|
+
function isClientAllowed(req) {
|
|
83
|
+
var list = (typeof process.gina === 'object' && process.gina && Array.isArray(process.gina._adminAllowList))
|
|
84
|
+
? process.gina._adminAllowList
|
|
85
|
+
: DEFAULT_ALLOW_LIST;
|
|
86
|
+
return _isAllowedWithList(req, list);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
module.exports = {
|
|
90
|
+
isClientAllowed : isClientAllowed,
|
|
91
|
+
_isAllowedWithList : _isAllowedWithList,
|
|
92
|
+
DEFAULT_ALLOW_LIST : DEFAULT_ALLOW_LIST
|
|
93
|
+
};
|
|
@@ -20,6 +20,7 @@ var scan = require('../port/inc/scan');
|
|
|
20
20
|
* Usage:
|
|
21
21
|
* gina bundle:add <bundle_name> @<project_name>
|
|
22
22
|
* gina bundle:add <bundle_name> @<project_name> --start-port-from=<port_number>
|
|
23
|
+
* gina bundle:add <bundle_name> @<project_name> --ignore-ports=<port[,port...]>
|
|
23
24
|
* gina bundle:add <bundle_name> @<project_name> --scope=<scope> --env=<env>
|
|
24
25
|
*
|
|
25
26
|
* @class Add
|
|
@@ -35,7 +36,9 @@ function Add(opt, cmd) {
|
|
|
35
36
|
|
|
36
37
|
var self = {
|
|
37
38
|
// --start-port-from
|
|
38
|
-
startFrom: null
|
|
39
|
+
startFrom: null,
|
|
40
|
+
// --ignore-ports — extra ports to exclude from the availability scan
|
|
41
|
+
ignorePorts: []
|
|
39
42
|
}
|
|
40
43
|
, local = {
|
|
41
44
|
// bundle index while searching or browsing
|
|
@@ -77,6 +80,30 @@ function Add(opt, cmd) {
|
|
|
77
80
|
}
|
|
78
81
|
self.startFrom = port
|
|
79
82
|
}
|
|
83
|
+
|
|
84
|
+
if ( /^\-\-ignore\-ports\=/.test(process.argv[i]) ) {
|
|
85
|
+
let raw = process.argv[i].substring(process.argv[i].indexOf('=') + 1);
|
|
86
|
+
let entries = raw.split(/,/);
|
|
87
|
+
for (let e = 0, eLen = entries.length; e < eLen; e++) {
|
|
88
|
+
let p = entries[e].trim();
|
|
89
|
+
// tolerate empty tokens from trailing/duplicate commas (e.g. 3000,,3001,)
|
|
90
|
+
if ( p === '' ) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if ( /[^0-9]+/.test(p) ) {
|
|
94
|
+
portErr = new Error('--ignore-ports must be a comma-separated list of integers');
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
// keep as STRING — scan.js compares opt.ignore.indexOf(''+port)
|
|
98
|
+
// and getPortsList() likewise stores string ports
|
|
99
|
+
if ( self.ignorePorts.indexOf(p) < 0 ) {
|
|
100
|
+
self.ignorePorts.push(p)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (portErr) {
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
80
107
|
}
|
|
81
108
|
|
|
82
109
|
if (portErr) {
|
|
@@ -145,8 +172,17 @@ function Add(opt, cmd) {
|
|
|
145
172
|
local.envFileSaved = false;
|
|
146
173
|
|
|
147
174
|
// find available port
|
|
175
|
+
// merge the user-supplied --ignore-ports into the already-assigned
|
|
176
|
+
// ports so the scan skips both (strings, matching scan.js's
|
|
177
|
+
// opt.ignore.indexOf(''+port) and getPortsList()'s string ports)
|
|
178
|
+
var ignoreList = getPortsList();
|
|
179
|
+
for (let ig = 0, igLen = self.ignorePorts.length; ig < igLen; ig++) {
|
|
180
|
+
if ( ignoreList.indexOf(self.ignorePorts[ig]) < 0 ) {
|
|
181
|
+
ignoreList.push(self.ignorePorts[ig])
|
|
182
|
+
}
|
|
183
|
+
}
|
|
148
184
|
options = {
|
|
149
|
-
ignore :
|
|
185
|
+
ignore : ignoreList,
|
|
150
186
|
limit : getBundleScanLimit(bundle),
|
|
151
187
|
startFrom : self.startFrom
|
|
152
188
|
};
|
|
@@ -12,7 +12,21 @@
|
|
|
12
12
|
|
|
13
13
|
$ gina bundle:add <bundle_name> @<project_name>
|
|
14
14
|
Or
|
|
15
|
-
$ gina bundle:add <bundle_name> @<project_name> --start-port-from
|
|
15
|
+
$ gina bundle:add <bundle_name> @<project_name> --start-port-from=<port_number>
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
Excluding specific ports from the scan
|
|
19
|
+
----------
|
|
20
|
+
By default, ports already assigned to the project's bundles (and the
|
|
21
|
+
reserved 4100-4199 range) are skipped automatically. To also skip a list
|
|
22
|
+
of specific ports while scanning, pass --ignore-ports with a comma-separated
|
|
23
|
+
list of port numbers:
|
|
24
|
+
|
|
25
|
+
$ gina bundle:add <bundle_name> @<project_name> --ignore-ports=3000,3001,8080
|
|
26
|
+
|
|
27
|
+
Combine with --start-port-from to move the scan window and skip ports:
|
|
28
|
+
|
|
29
|
+
$ gina bundle:add <bundle_name> @<project_name> --start-port-from=4200 --ignore-ports=4250,4300
|
|
16
30
|
|
|
17
31
|
|
|
18
32
|
Adding multiple
|
|
@@ -50,8 +50,20 @@ function Lib() {
|
|
|
50
50
|
//this one must move to Dev since it's dev related
|
|
51
51
|
Domain : _require('./domain'),
|
|
52
52
|
Model : _require('./model'),
|
|
53
|
-
|
|
54
|
-
merge
|
|
53
|
+
// #B32-residual (measured 2026-06-16) — plain require, NOT _require.
|
|
54
|
+
// Collection/merge/uuid are stateless leaf utilities new'd per request from
|
|
55
|
+
// gen-0 bindings captured in load-once modules (server.isaac.js:34
|
|
56
|
+
// `const Collection = lib.Collection`, used per request at :853 in onPath).
|
|
57
|
+
// With _require they are evicted from require.cache every refreshCore(), so each
|
|
58
|
+
// per-request `new Collection()` is a cache-miss that pushes a fresh merge/uuid
|
|
59
|
+
// child Module onto the gen-0 (evicted-but-retained) collection Module — which
|
|
60
|
+
// pruneDeadModuleChildren() never reaches (it walks require.cache keys only),
|
|
61
|
+
// accumulating ~2 dead Modules/request (dev-mode OOM). Plain require = never
|
|
62
|
+
// evicted = cache-hit = Node dedupes the children = flat. Verified standalone:
|
|
63
|
+
// gen-0 collection .children 0->1000 over 500 reqs with _require, pinned at 2
|
|
64
|
+
// with require. Same precedent as logger/job/State/instrument below.
|
|
65
|
+
Collection : require('./collection'),
|
|
66
|
+
merge : require('./merge'),
|
|
55
67
|
generator : _require('./generator'),//move to gina.dev
|
|
56
68
|
Proc : _require('./proc'),
|
|
57
69
|
Shell : _require('./shell'),
|
|
@@ -64,12 +76,17 @@ function Lib() {
|
|
|
64
76
|
logger : require('./logger'),
|
|
65
77
|
math : _require('./math'),
|
|
66
78
|
routing : _require('./routing'),
|
|
67
|
-
|
|
79
|
+
// #B32-residual — plain require: archiver is a `new Archiver()` EventEmitter
|
|
80
|
+
// SINGLETON (archiver/src/main.js:510). _require re-instantiated it every
|
|
81
|
+
// refreshCore() (per-request churn) and left each prior instance pinned via the
|
|
82
|
+
// gen-0 lib registry — it was the named instance in the leak's heap snapshot.
|
|
83
|
+
// A singleton must not hot-reload (same reason as logger/job/State/instrument).
|
|
84
|
+
archiver : require('./archiver'),
|
|
68
85
|
cmd : _require('./cmd'),
|
|
69
86
|
SessionStore : _require('./session-store'),
|
|
70
87
|
SwigFilters : _require('./swig-filters'),
|
|
71
|
-
Cache :
|
|
72
|
-
uuid :
|
|
88
|
+
Cache : require('./cache'), // #B32-residual — plain require (leaf class held at gen-0 via server.isaac.js:35; Cache._events is a Collection). See Collection note above.
|
|
89
|
+
uuid : require('./uuid'), // #B32-residual — plain require (pushed as a child of the gen-0 collection module per `new Collection()`). See Collection note above.
|
|
73
90
|
// #R1 — WatcherService: fs.watch-based file-change registry. Class is hot-reloadable;
|
|
74
91
|
// instantiated once per bundle in gna.js:onStarted and stored as gna.watcher.
|
|
75
92
|
Watcher : _require('./watcher'),
|
|
@@ -89,6 +106,11 @@ function Lib() {
|
|
|
89
106
|
// lifecycle hook that populates the HTTP counter + histogram. Opt-in
|
|
90
107
|
// via app.json `metrics.enabled`.
|
|
91
108
|
metrics : _require('./metrics'),
|
|
109
|
+
// #S7 — admin /_gina/* IP-allowlist gate (isClientAllowed). Functional
|
|
110
|
+
// sibling of metrics above, but a PLAIN require (NOT _require): a
|
|
111
|
+
// stateless pure-function leaf with no instance/singleton state to
|
|
112
|
+
// hot-reload — same #B32-residual precedent as merge / uuid / Collection.
|
|
113
|
+
admin : require('./admin'),
|
|
92
114
|
// #AI6 — Async-job primitive. Holds an in-memory job registry, a
|
|
93
115
|
// concurrency-limited worker, and a self-contained unref'd setInterval
|
|
94
116
|
// sweep timer at module scope. Like State / logger below, it MUST use a
|
|
@@ -1519,7 +1519,13 @@ function Routing() {
|
|
|
1519
1519
|
namespace : routing[name].namespace || undefined,
|
|
1520
1520
|
url : safeDecodeURI(pathname), /// avoid %20 — #B30 malformed-%-safe
|
|
1521
1521
|
rule : routing[name].originalRule || name,
|
|
1522
|
-
|
|
1522
|
+
// #B52-residual finding-2: clone so the matcher's in-place param substitution
|
|
1523
|
+
// (fitsWithRequirements / checkRouteParams rewrite param.{path,namespace,file,title})
|
|
1524
|
+
// does NOT mutate the shared config singleton — getRouteByUrl's `routing` is
|
|
1525
|
+
// config.getRouting() (server-side) / gina.config.routing (client), both by reference.
|
|
1526
|
+
// Mirrors server.js:4852 and the middleware clone on the next line.
|
|
1527
|
+
//param : routing[name].param,
|
|
1528
|
+
param : JSON.clone(routing[name].param),
|
|
1523
1529
|
//middleware: routing[name].middleware,
|
|
1524
1530
|
middleware : JSON.clone(routing[name].middleware),
|
|
1525
1531
|
bundle : routing[name].bundle,
|
|
@@ -1533,6 +1539,11 @@ function Routing() {
|
|
|
1533
1539
|
if (isRoute.past) {
|
|
1534
1540
|
route = JSON.clone(routing[name]);
|
|
1535
1541
|
route.name = name;
|
|
1542
|
+
// #B52-residual finding-2: getRouteByUrl returns `route` (a fresh clone of the
|
|
1543
|
+
// singleton), NOT the mutated `params`. Carry the per-request substituted param
|
|
1544
|
+
// (rewritten on the private clone above) onto the returned route so the result is
|
|
1545
|
+
// correct AND the singleton keeps its `:placeholder`(s) for the next request.
|
|
1546
|
+
route.param = params.param;
|
|
1536
1547
|
|
|
1537
1548
|
matched = true;
|
|
1538
1549
|
isRoute = {};
|
package/gna.js
CHANGED
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
'use strict';
|
|
16
16
|
|
|
17
17
|
// Framework core — the main gna module (lifecycle hooks, lib, etc.)
|
|
18
|
-
var _gna = require('./framework/v0.5.
|
|
18
|
+
var _gna = require('./framework/v0.5.4/core/gna');
|
|
19
19
|
|
|
20
20
|
// SuperController and EntitySuper — loaded from their source modules
|
|
21
|
-
var SuperController = require('./framework/v0.5.
|
|
22
|
-
var EntitySuper = require('./framework/v0.5.
|
|
21
|
+
var SuperController = require('./framework/v0.5.4/core/controller');
|
|
22
|
+
var EntitySuper = require('./framework/v0.5.4/core/model/entity');
|
|
23
23
|
|
|
24
24
|
// uuid — from the lib registry
|
|
25
|
-
var uuid = require('./framework/v0.5.
|
|
25
|
+
var uuid = require('./framework/v0.5.4/lib/uuid');
|
|
26
26
|
|
|
27
27
|
module.exports = {
|
|
28
28
|
|
package/llms.txt
CHANGED
|
@@ -911,7 +911,7 @@ Dev-mode query instrumentation captures every database query tied to the current
|
|
|
911
911
|
|
|
912
912
|
172. **Late response-API calls on a released response must no-op, never crash (#B31, 2026-06-12, commit `27aa95a9`, shipped `0.5.1-alpha.2`).** Every response terminal exit releases the per-request refs (`local.req/res/next = null`) — and `redirect()` releases them AND THEN calls `next()`, so the middleware chain continues into the controller action with the refs already null. Any later response-API call on the same request therefore ran against a released response, and two entry points turned that into a process kill rather than a no-op: `throwError` normalizes every 1-/2-arg call shape to `res = local.res` and read `typeof(res.getHeaders)` off the null (`TypeError: Cannot read properties of null (reading 'getHeaders')`, no application frames), and `headersSent()` read `typeof(_res.stream)` off the null — both uncaughtExceptions the process supervisor escalates to SIGTERM, killing the bundle plus every in-flight request. Field shape: an auth middleware that 301-redirects unauthenticated requests to a login route and lets the chain continue makes the crash deterministic on every unauthenticated hit — and the crash-respawn loop keeps every process cold, which can masquerade as a separate "valid sessions never authenticate" bug (each request lands on a freshly-respawned process whose session-store connector hasn't warmed). Fix: `headersSent()` reports a released response as already-sent (single chokepoint — every `!headersSent()` caller no-ops), and `throwError` logs the serialized late error (the warn now names what previously died as an opaque uncaughtException) and returns false, mirroring its renderingStack guard; live-response paths are byte-identical. Same crash class as the malformed-percent decode DoS: fix the throw site, never widen the uncaughtException net. Reusable repro recipe: `controller.js` loads standalone — inject the framework dir into NODE_PATH + `Module._initPaths()`, require the framework `helpers` (injects the `_`/`getPath`/`requireJSON` globals), `setPath('gina', { core: <fw>/core })`, then `SuperController.createTestInstance({req, res, next, options})` with a minimal mock response + `renderTEXT()` as the lightest terminal exit reproduces any released-response sequence against the real class.
|
|
913
913
|
|
|
914
|
-
173. **Dev-mode hot-reload eviction leaked the whole framework module graph per request via module.children (#B32, 2026-06-12, commit `3ad449f8`).** Node pushes every cache-miss require()'s fresh Module onto the REQUIRING module's children array and dedupes only on cache hits — so the per-request delete-and-re-require cycles (refreshCore in the isaac engine re-requiring lib/index.js + plugins/index.js; refreshCoreDependencies in the router re-requiring the controller pair; lazy in-function requires of evicted libs) made long-lived parents accumulate one dead Module per eviction, each pinning its entire evaluated exports graph. Measured on a minimal starter bundle in dev: ~1.8 MB of post-GC live heap retained per request, dead-linear (435.5 ± 0.3 MB per 250 requests), require.cache at 164 entries vs 14,178 reachable Modules, heap-limit OOM (V8 abort, exits SIGABRT) at ~2400 requests — presenting upstream as HTTP/2 PING timeouts (the GC death spiral freezes the event loop) then ECONNREFUSED, then a supervisor respawn loop that keeps every process cold. Fix: a pruneDeadModuleChildren() sweep at the end of BOTH eviction cycles walks require.cache and keeps only children whose resolved id still maps to that same instance — children is diagnostic metadata (nothing in Node resolution reads it), so pruning never unloads a module still referenced elsewhere. Post-fix: flat ~32 MB live heap across 3000 requests, 168 reachable vs 164 cached. Prod was never affected (no eviction + cache-hit dedup). Known residual, same class, deliberately deferred: the CLI daemon evicts config JSONs per command (cmd helper + requireJSON) with no sweep — KB-scale at human command cadence; run the same sweep at command dispatch if it ever measures as a problem. Tests: test/core/module-children-prune.test.js (source pins + pure-logic replica + subtract).
|
|
914
|
+
173. **Dev-mode hot-reload eviction leaked the whole framework module graph per request via module.children (#B32, 2026-06-12, commit `3ad449f8`).** Node pushes every cache-miss require()'s fresh Module onto the REQUIRING module's children array and dedupes only on cache hits — so the per-request delete-and-re-require cycles (refreshCore in the isaac engine re-requiring lib/index.js + plugins/index.js; refreshCoreDependencies in the router re-requiring the controller pair; lazy in-function requires of evicted libs) made long-lived parents accumulate one dead Module per eviction, each pinning its entire evaluated exports graph. Measured on a minimal starter bundle in dev: ~1.8 MB of post-GC live heap retained per request, dead-linear (435.5 ± 0.3 MB per 250 requests), require.cache at 164 entries vs 14,178 reachable Modules, heap-limit OOM (V8 abort, exits SIGABRT) at ~2400 requests — presenting upstream as HTTP/2 PING timeouts (the GC death spiral freezes the event loop) then ECONNREFUSED, then a supervisor respawn loop that keeps every process cold. Fix: a pruneDeadModuleChildren() sweep at the end of BOTH eviction cycles walks require.cache and keeps only children whose resolved id still maps to that same instance — children is diagnostic metadata (nothing in Node resolution reads it), so pruning never unloads a module still referenced elsewhere. Post-fix: flat ~32 MB live heap across 3000 requests, 168 reachable vs 164 cached. Prod was never affected (no eviction + cache-hit dedup). Known residual, same class, deliberately deferred: the CLI daemon evicts config JSONs per command (cmd helper + requireJSON) with no sweep — KB-scale at human command cadence; run the same sweep at command dispatch if it ever measures as a problem. **Second residual of the same class, found + fixed (#B32-residual, 2026-06-16, commit `8d6a4c5c`):** the prune walks require.cache keys ONLY, so it cannot reach a parent Module that was evicted from require.cache but is retained elsewhere — and collection/merge/uuid/cache/archiver were `_require`'d (evicted every refreshCore) while load-once modules capture them at gen-0 (`server.isaac.js:34 const Collection = lib.Collection`, new'd per request at :853). So each per-request `new Collection()` was a cache-miss that pushed a fresh merge/uuid child Module onto the gen-0 (evicted-but-retained) collection Module: +2 dead Modules/request, off-require.cache, prune-blind, ending in a dev-mode OOM under sustained traffic (measured ~+43 MB per 500 requests in a consuming bundle's long dev/e2e run). Fix: plain `require` those five leaf/singleton libs (never evicted -> cache-hit -> Node dedupes the children -> flat), matching the logger/job/State/instrument precedent in lib/index.js. Verified standalone: gen-0 collection .children 0->1000 over 500 reqs with `_require`, pinned at 2 with `require`. Tests: test/core/module-children-prune.test.js (source pins + pure-logic replica + subtract); the residual adds §04 (locks the five libs to plain require) + §05 (replicates the gen-0-off-cache leak + the resident-child fix). **Completeness audit (2026-06-16): the gen-0-binding class is CLOSED.** Swept all remaining `_require`'d libs for the same triple — HOT + gen-0-captured by a load-once module + per-request-invoked + the per-request code require()s a HOT sibling. The only per-request gen-0 HOT invocations from load-once modules are `inherits` (router.js :594/595/597/664/890 + couchbase index.js:718) and `routing` methods (server.js): `lib/inherits/src/main.js` has ZERO require() — a pure Object.create prototype-chain builder cannot push a child (MEASURED +0 children over 200 reqs on the real module, instrument validated by a +200 leaking control) — and routing's only in-method require is the non-HOT `./radix` (absent from lib/index.js, untouched by both eviction cycles -> permanent cache-hit; the inherits/merge requires at routing main.js:60-64 sit in the Routing() constructor = singleton module-eval-once). swig-filters/nunjucks-filters DO require routing/i18n in their constructors but are startup-only (server.js:513) or built per-request from the EVICTED render-nunjucks delegate reading live lib (gen-N/in-cache -> prune-covered); helpers/path->async is the in-cache-parent original-#B32 case; cmd->proc is CLI-command-cadence. No other gen-0-bound `_require`'d lib leaks. Regression guard: module-children-prune.test.js §06 pins lib/inherits to zero require().
|
|
915
915
|
|
|
916
916
|
174. **`throwError` — call signatures, status-code preservation, render-error interception, and fail-closed error-response `stack` hygiene** (replaces individual entries #10, #21, #26, #105, #110, #132) — `self.throwError` accepts four shapes: `(errorObj|Error)` 1-arg; `(code, Error|string)` 2-arg, dispatched via a function-top normalization shift that preserves the explicit code (`throwError(404, new Error('not found'))` sends 404 — earlier releases fell back to 500, and the `new Error(...)` wrapping workaround from that era still works unchanged); `(code, errorObj)` 2-arg, intentionally NOT shifted — it flows through the `arguments.length < 3` branch whose `code = res || 500` reaches the explicit code, and including errorObj in the shift detection would break exactly that case; `(res, code, string|Error)` 3-arg (explicit code preserved). Always `return self.throwError(...)` immediately in a controller action — it is a terminal response, and any later response-API call runs against a released response (guarded to warn + no-op since 0.5.1-alpha.2 instead of crashing the bundle). Calling `self.render(err)` with a non-2xx `data.page.data.status` and a defined `data.page.data.error` is intercepted before template rendering and routed through `throwError` automatically; object-valued `error`/`message` fields are normalised to strings first (no `[object Object]`), and the same normalized string feeds the server-side `console.error('[render] ...')` log, so wire and log carry identical readable text. Error responses are scope-gated FAIL-CLOSED: unless `NODE_SCOPE_IS_LOCAL` is explicitly `true`, the server-side `stack` is stripped from BOTH the JSON error body AND the fallback HTML error page's `<pre class="stack">` block — the gate is strip-unless-local, not strip-only-if-prod, so an unset scope on a fresh deployment still strips and internals (file paths, frames, library versions) never leak; local scope keeps the stack on the wire for the dev toolbar's data-xhr panel. Custom error templates remain consumer-owned (a view rendering the error object's `stack` is the consumer's call), and passing `err.stack` as the message argument surfaces it in the un-gated `error` STRING — sanitize that at the call site.
|
|
917
917
|
|
|
@@ -934,3 +934,29 @@ Dev-mode query instrumentation captures every database query tied to the current
|
|
|
934
934
|
183. **The framework command socket must accumulate-and-guard-parse incoming chunks — an unguarded `JSON.parse(data.toString())` on each raw `'data'` chunk is a crash vector (2026-06-14, commit `c4694bde`).** `bin/cmd`'s `launchFramework` socket handler parsed every TCP chunk directly as JSON. The client (`bin/cli`) sends `JSON.stringify(process.argv)` in a SINGLE write, but TCP may split or coalesce it across chunks, and a partial / empty / non-JSON payload makes `JSON.parse` throw a `SyntaxError`; with no try/catch and no request lifecycle around it, the throw reaches `proc.js`'s `uncaughtException` handler → emerg + `dismiss(pid, 'SIGTERM')`, dropping the command and risking a daemon teardown (same throw-site crash family as the malformed-`%` decode DoS and the boot-exit-flush truncation entries). Fix: a per-connection `_payload` accumulator (declared in the `net.createServer(function(conn){…})` closure so each connection has its own buffer); `conn.on('data')` appends, then `try { argv = JSON.parse(_payload) } catch { return }` — a partial chunk keeps accumulating until complete, a non-JSON/empty payload never parses and is ignored, and on success the buffer resets for any further command on the connection. An `!Array.isArray(argv)` guard (warn + drop) closes the residual path, since `argv.join`/`argv[0]=` sit OUTSIDE the parse try and would throw on a valid-but-non-array payload. The parse catch stays SILENT (no log): it fires on a legitimate incomplete chunk too, before it is known whether the payload will complete, so a "parse failed" log there would be misleading. Rule: never `JSON.parse` a raw socket chunk unguarded — accumulate and try/catch, and guard the post-parse shape.
|
|
935
935
|
|
|
936
936
|
184. **`~/.gina` state files must be written ATOMICALLY (temp + rename) — a truncate-in-place `fs.writeFileSync` lets a concurrent boot read a torn/empty file and crash (#B43, 2026-06-14, commit `519788ea`).** The five state files (`main.json`/`projects.json`/`settings.json`/`env.json`/`locals.json`) were written with a bare in-place `fs.writeFileSync(target, data)` at the two write sites — the StateStore JSON sidecar (`lib/state.js` `this.write`) and the legacy fallback (`lib/generator/index.js` `createFileFromDataSync`, the single chokepoint for all ~150 state-file writes). `writeFileSync` opens with `O_TRUNC` (target → 0 bytes) then streams, so a concurrent reader catches either an EMPTY file (the post-truncate window, payload-size-independent) or a PARTIAL one (mid-`write()`, widening with file size). Every state-file READ path is FATAL on a parse failure: `requireJSON` does `console.emerg` + `process.exit(1)` for non-`/controllers/` paths, and the more common plain `require('*.json')` boot reads (`gna.js`, `config.js`, framework `start.js`, six `init.js` sites) throw an uncaught `SyntaxError` → process death. So a concurrent fleet boot (many bundles/containers booting against one `~/.gina`) intermittently crashed when a reader caught a writer mid-write; the supervisor respawned and a later non-concurrent read succeeded, presenting as an intermittent crash. MEASURED with a concurrent reader/writer race on the exact `fs.writeFileSync` primitive (empty + partial reads → `JSON.parse` `SyntaxError`; the empty-read window is always present, the partial window widens with file size). Fix: both sites write a same-dir temp (`<target>.<pid>.<seq>.tmp`) then `fs.renameSync` — `rename(2)` is atomic within a filesystem, so a reader sees the complete old file or the complete new one, never a torn one; `chmod` the temp before rename, unlink-on-failure + rethrow. The SQLite `INSERT` was already atomic — only the JSON sidecar that readers consume was torn. Because `createFileFromDataSync` is the single write chokepoint, the two edits close the window for ALL readers (`requireJSON`, plain `require`, `gina-container`'s raw `JSON.parse`). A reader-side retry in `requireJSON` was DECLINED — it covers only the `requireJSON` minority (not the plain-`require` majority), defends a window the write fix already closes, and pollutes the hot general-purpose helper while masking genuine corruption. Rule: any `~/.gina` state-file write goes through the atomic temp+rename, never a bare in-place `writeFileSync`. Tests: `test/lib/state-atomic-write.test.js` (block-scoped source pins on both sites + fs-spy behavioural on the real generator legacy + StateStore sidecar paths + the deterministic torn-read consequence).
|
|
937
|
+
|
|
938
|
+
185. **`gina bundle:add --ignore-ports=<port[,port...]>` excludes specific ports from the bundle port scan (2026-06-15, commit pending).** `bundle:add` (and import mode, `bundle:add --import`) scans for available ports starting at 3100 (or `--start-port-from`), already skipping ports assigned to the project's bundles plus the reserved 4100-4199 range; `--ignore-ports` adds a user-supplied comma-separated list to that exclusion set. The flag is whitelisted in `lib/cmd/bundle/arguments.json` (so `getParams()` routes it to `cmd.params`, not the node-flag bucket — though `bundle:add` is offline and reads `process.argv` directly, whitelisting is consistency+hygiene, not strictly required) and parsed in `add.js` `init()` (mirroring `--start-port-from`): split on the first `=`, CSV-split, `.trim()` each, skip empty tokens (tolerates `3000,,3001,`), integer-shape validation (`/[^0-9]+/` → error+exit on a non-integer), de-dup. **Values are kept as STRINGS and unioned into `getPortsList()` before the scan, because `scan.js` skips via `opt.ignore.indexOf(''+port)` (string compare) and `getPortsList()` itself stores `''+p` — `parseInt`-ing them would silently break the skip.** Out-of-range entries (e.g. 70000) are harmless no-ops since the scan window caps at `maxEnd` 49151, so validation is integer-shape only (matching the sibling flag), no range check. Composable with `--start-port-from`. Tests: `test/unit/bundle-add-ignore-ports.test.js` (source pins + parse/merge replica) + a scattered multi-port ignore case in `test/unit/port-scan.test.js`.
|
|
939
|
+
|
|
940
|
+
186. **FormValidator data-rule bodies must handle STRING inputs — the engine runs server-side (`backendInit` → `new FormValidator(fields)`) AND in the browser bundle, and BOTH feed it strings (`.value` + `application/x-www-form-urlencoded` bodies are always strings); a rule-body fix needs a prod dist rebuild AND flips the live-engine characterization tests (#B46 `isFloat` + #B47 `isDate` 2026-06-15; #B48 `isDate` chaining 2026-06-17).** `core/plugins/lib/validator/src/form-validator.js` is compiled into `gina.min.js` (the RequireJS bundle aliases `lib/form-validator` in `core.js`), so any rule-body edit needs the prod build (CI tool flags, baseline-build-first → only the 4 `gina.*` artifacts change) AND the section-locked characterization tests in `test/lib/validator-engine-rules.test.js` flip by design (they lock the surprising-but-current behavior on purpose — fixing a rule deliberately breaks its lock). **#B46 (`5576a8bd`):** `isFloat` gated on `Number(val) === val`, true only for a real JS number, so a string `"1.5"` was rejected server-side; fixed by `var n = Number(val); isValid = Number.isFinite(n) && n % 1 !== 0` (a whole number still fails — isFloat requires a fractional part). `isNumber` already accepted string floats (the safe pre-fix alternative); the documented `toFloat()` remedy references `document` (throws headless) and is now unnecessary for plain validation. **#B47 (`eb17d9c9`):** `isDate` rebuilt the candidate string FROM THE MASK keeping its separators then called `new Date(str)`, so a slash mask `dd/mm/yyyy` + `15/06/2023` parsed as US `MM/DD` → month 15 → Invalid Date → wrongly rejected; fixed by extracting numeric components from the mask tokens (`/y/i`→year, `/m/i`→month, `/d/i`→day) and building `new Date(y, mo-1, d)` — but a naive component build ROLLS OVER (`new Date(2023,12,45)` is a valid date; `Feb 30`→`Mar 2`), so a **round-trip check** (the constructed date's `getFullYear/getMonth/getDate` must equal the inputs) is required to keep impossible dates rejected. **#B48 (`954f6a7a`, 2026-06-17):** `isDate` returned the parsed `Date` (not the field) on its valid path, so `field.isDate().isX()` chained off a Date and broke; now returns `self[this.name]` (the field) like every other rule, with the parsed Date preserved on the field's `.value` so `field.isDate(mask).format(...)` still renders it via the field's own `format` method (the one documented `.format()` consumer is byte-identical post-fix). General rule: a typed/numeric validator rule must coerce or parse explicit components — never assume the input is already a typed JS value, because every real input path delivers a string.
|
|
941
|
+
|
|
942
|
+
187. **Every uploaded file must map to a CONFIGURED upload group — an unconfigured group is rejected (400) instead of streaming through unchecked, and `untagged` is no longer hardcode-exempt from its own limits (#B50, 2026-06-16, commit `8072d1eb`).** `core/server.js`'s multipart busboy `'file'` handler ran the `allowedExtensions` + `isMultipleAllowed` checks ONLY inside `if (typeof(group) != 'undefined' && group != 'untagged' && opt.groups[group])`; every other case — no group, `untagged`, or an unknown group name — streamed through UNCHECKED, so a client could bypass a group's allow-list by tagging a file with any unconfigured group (only the global `maxFieldsSize` 431 gate applied). Fix: resolve each file's group (no/empty group → the default `untagged`); `throwError(response, 400, …)` BEFORE the temp file is created when the resolved group is not in `opt.groups`; and drop the `&& group != 'untagged'` special-case so `untagged` obeys its own config like any other group. The shipped `settings.json` `untagged` default was flipped `isMultipleAllowed: false → true` so the default — and the client's default-`untagged` path (`validator/src/main.js:1886`) — stays permissive = untagged's CURRENT effective behavior (multiple allowed, because it was bypassed), making the change back-compat-neutral for new bundles; existing bundles that set untagged `false`, or never configured `upload.groups`, must adjust (`Security` changie). Honest residual (NOT closed): untagged's default `allowedExtensions: '*'` still allows any extension, so switching to `untagged` dodges a restrictive NAMED group's allow-list unless the app configures untagged restrictively — now possible, because the config is finally honored. `server.js` is server-side (not in the browser bundle) → no dist rebuild. Rule: a per-group/per-tenant restriction is only a control if the UNCONFIGURED / default case is denied or constrained, never silently waved through. Tests: `test/core/upload-groups.test.js` (source pins comment-stripped so the negative `group != 'untagged'` pin doesn't trip on the commented-out old block + a classify replica + the shipped-default pin).
|
|
943
|
+
|
|
944
|
+
188. **The multipart upload handler now honours the configured destination dir and the maxFields / maxFieldsSize limits — three documented settings.json keys were inert (#B49 + #B51, 2026-06-16, commits `0df499a6` + `15ceff06`).** `core/server.js`'s `multipart/form-data` branch carried three dead `upload.*` config keys: (1) **#B49** — it streamed each file via `opt.uploadDir`, a key the shipped `settings.json` never sets (it defines `upload.tmpPath` + per-group `path`, and nothing mapped `tmpPath`→`uploadDir`), so every upload landed in `os.tmpdir()` and the documented dir keys did nothing; (2) **#B51** — `upload.maxFields` (default 1000) was declared but read nowhere, so a group allowing multiple files accepted an UNBOUNDED count (only the binary per-group `isMultipleAllowed` capped anything); (3) **#B51** — `maxFieldsSize` dropped its unit suffix (`parseInt("512K")` → 512, then compared as 512 MB, so `"512K"` silently meant 512 MB). Fixes: (#B49) global dir = `opt.uploadDir || opt.tmpPath || os.tmpdir()`, a per-group `path` override at both write sites, AND an mkdir-if-missing before `createWriteStream` — required because the writeStream `'error'` handler is only attached later, in the busboy `'finish'` loop, so a missing CUSTOM dir would emit an unhandled ENOENT during streaming and crash the bundle (the default `<project>/tmp` is created at boot, but a custom dir is not); (#B51) a global `maxFields` file-count cap (`throwError(400)` once `fileCount > maxFields`, with `0`/unset/NaN disabling it), and a local `parseSize` helper reading B/KB/MB/GB (a bare number = MB for back-compat) into bytes so `content-length` is compared in bytes. The `${tmpPath}` placeholder in `tmpPath`/`path` resolves to an absolute dir at config-load via `whisper` (→ `<project>/tmp`), so the fix reads a real value. Back-compat: the shipped `"2MB"` is unchanged; a non-MB `maxFieldsSize` suffix now means what it says (a tighter limit) — a `Fixed` changie note. `server.js` is server-side (not in the browser bundle) → no dist rebuild. Rule: a documented config key is only real if a code path reads it — grep the consumer before assuming a setting works. Tests: `test/core/upload-config.test.js` (source pins comment-stripped per the negative-pin trap + dir-resolution / parseSize / maxFields replicas + a real-fs throwaway-dir mkdir behavioural test).
|
|
945
|
+
|
|
946
|
+
189. **An async render delegate must capture per-request inherited refs FUNCTION-scoped, not module-scoped — a module-scoped `self`/`local` races across concurrent renders (#INS10 race fix, 2026-06-17, commit `8674c514`).** `controller.render-swig.js` assigned `self`/`local` at MODULE scope (no `var`), so two concurrent renders shared one binding. Because the Inspector emit (the #INS10 prod-window egress + the dev `inspector#data` emit) reads `self`/`local` AFTER the layout `await`, a render suspended at that await could have its `self`/`local` overwritten by another request and then emit the OTHER request's `_queryLog`/`_timeline`. LOW severity — the channel is authenticated operator-only + time-boxed and the payload is the operator's own bundle (a correctness glitch, not an external leak) — but a real cross-request bleed. Fixed by capturing them function-scoped (`var self = deps.self; var local = deps.local;`) at the render() deps-unpack and dropping them from the module-level inherited-ref chain, matching the #M1 `req`/`res`/`_next` captures and `render-nunjucks.js` (always function-scoped, hence always race-clean). `getData`/`hasViews`/`SwigFilters`/`headersSent` stay module-scoped on purpose: they are read BEFORE the first await, so they are not a race vector (only the measured vector was changed). `render-swig.js` is server-side (not in the browser bundle) → no dist rebuild. Rule: any async (multi-`await`) render delegate that reads a per-request ref AFTER an await must hold it in a function-scoped capture, never a module-scoped binding. Tests: `render-swig.test.js` §12 (a2).
|
|
947
|
+
|
|
948
|
+
190. **Per-bundle `/_gina/*` Inspector endpoints must derive their base URL with the 3-fallback resolver (`?target=` → opener pathname → strip), not a bare `window.location.pathname` strip — a bare strip misroutes to the proxy's default bundle in reverse-proxy multi-bundle setups (2026-06-17, commit `f04cf52c`).** Where several bundles share a host and differ only by a path prefix (`/a` → bundle A, `/b` → bundle B), the Inspector SPA's `fetchLiveIndexes` (`/_gina/indexes`) and `tryServerLogs` (`/_gina/logs`) built their URL from `window.location.pathname.replace(/\/_gina\/inspector.*$/, '')` — the Inspector's OWN path — so a bare `/_gina/logs` hit the proxy's default bundle, not the monitored one. Fixed by extracting `toggleReveal`'s existing 3-fallback resolver into a shared `resolveBundleBase()` and routing those two through it. `/_gina/agent` is NOT a misroute vector (the architecture note that flagged it overstated): `tryAgent`/`tryAgentWS` are `?target=`-gated and `tryAgentPassive` already uses the opener-pathname fallback (verified). `toggleReveal`/`tryAgentPassive`/refresh-re-reveal keep their inline copies (pinned by `inspector.test.js` §54/§55/§56) — full dedup is a deferred cleanup needing a test-pin update. SPA src edit → prod dist rebuild: `inspector.js` is a verbatim src→dist copy, so only `dist/.../inspector/inspector.js` changes (no `gina.min.*` drift). Rule: any new per-bundle `/_gina/*` consumer in the SPA must call `resolveBundleBase()`, never a bare pathname strip. Tests: `inspector.test.js` §79. **Follow-up (2026-06-17, commit `0066c78e`):** the 3 inline copies (`toggleReveal`, `tryAgentPassive`, refresh re-reveal) were folded into `resolveBundleBase()` — every per-bundle `/_gina/*` consumer now uses the one resolver. `tryAgentPassive` was a 2-fallback (no `?target=`); folding widens it to 3, but the `?target=` branch is inert there (it only runs when `source !== 'agent'`, i.e. no `?target=`). §54/§55/§56 pins re-aimed from inline-text greps to `resolveBundleBase()`-call assertions (the resolver's own 3-fallback/try-catch internals stay pinned in §79). inspector.js is a verbatim src→dist copy → only `dist/.../inspector/inspector.js` rebuilt (no `gina.min.*` drift). No behavior change (no changie).
|
|
949
|
+
|
|
950
|
+
191. **Inspector SPA input-hardening — validate every structured-localStorage read's SHAPE (not just try/catch the parse) and `escHtml` every value interpolated into `innerHTML` (2026-06-17, commit `af43f2bc`).** Two defense-in-depth gaps in `inspector.js`: (C) `loadFoldStore()` parsed `localStorage['__gina_inspector_folds']` inside a try/catch but returned the value with NO shape check — a corrupted/tampered key holding a JSON primitive (`42`/`true`/`"x"`) flowed to the un-try/caught `<details>` toggle handler, which runs `store[tab] = {}` on the primitive → strict-mode `TypeError` → fold persistence breaks on every toggle. Fixed with `return (o && typeof o === 'object' && !Array.isArray(o)) ? o : {}`, matching the sibling readers `getCustomOrder`/`getHiddenTabs`/`tryLocalStorage` that all shape-check. (D) `renderFormDataSections` interpolated a form-data section key into an `innerHTML` string as `'<h3 ...>' + keys[k] + '</h3>'` — the ONLY key/label interpolation in the SPA lacking `escHtml` (every sibling — `dkName`/`attr.name`/`key` — escapes). Not request-attacker-controlled today (the keys are framework-literal section names), so defense-in-depth, not a live XSS; fixed with `escHtml(keys[k])`. Both are SPA src edits → prod dist rebuild (`inspector.js` verbatim copy → only that dist file changes). Rule: a structured-localStorage read needs `JSON.parse`-in-try/catch AND a `typeof`/`Array.isArray` shape check; any value reaching `innerHTML` needs `escHtml`. Tests: `inspector.test.js` §80.
|
|
951
|
+
|
|
952
|
+
192. **The default Express engine now mirrors the admin `/_gina/info` + `/_gina/cache/stats` endpoints — they were Isaac-only (Express 404'd them), a `/_gina/*` endpoint-sync-rule violation (#S7 express-mirror, 2026-06-17, commit `52ee55e9`).** `server.isaac.js` served both admin-grade endpoints (process state — memory/uptime/version/HTTP-2 counters at `/_gina/info`; cache contents at `/_gina/cache/stats`) behind an IP allowlist, but the engine-agnostic `server.js` never registered them, so Express bundles 404'd both (fail-closed, but a parity gap — the binding rule is "Isaac is the source of truth, but every `/_gina/*` handler must also work under Express"). Fixed by duplicating the `isAdminClientAllowed(req)` helper VERBATIM into `server.js` module scope (byte-identical, source-pinned in `test/core/server.test.js` to stay in sync with the Isaac copy; a shared `lib.admin` extraction is a clean deferred follow-up — the duplicate matches the existing per-engine handler-mirror pattern, e.g. `/_gina/metrics` + `/_gina/jobs/:id`), and adding both handlers right after the metrics mirror, always-on + admin-gated (loopback default via `process.gina._adminAllowList`, which `gna.js` already seeded but `server.js` never consumed). Express uses the `response.setHeader`/`statusCode`/`end` idiom (not Isaac's `response.stream`/`_setPoweredByHeader`); the `/_gina/info` `http2` block stays `if (..._h2Metrics)`-guarded → omitted under Express (no HTTP/2 session metrics, correct degradation); `/_gina/cache/stats` builds a fresh `new lib.Cache()`, calls `.from(self.instance._cached)`, returns `.stats()`. `server.js` is server-side (not in the browser bundle) → no dist rebuild. Rule: a new always-on `/_gina/*` endpoint must land in BOTH engines, and admin-grade ones carry the IP-allowlist gate (never trusting X-Forwarded-For; `::ffff:` normalised; `[]` = deny-all; missing list → loopback). Tests: `server.test.js` #S7 (source pins + byte-identical sync guard + a behavioral replica mirroring `server.isaac.test.js` §08b). **Follow-up (2026-06-17, commit `d41483c1`):** the byte-identical duplicate was extracted into a shared `lib.admin` (a stateless pure-function leaf — plain `require('./admin')` in `lib/index.js`, NOT `_require`, per the #B32-residual precedent of merge/uuid/Collection); both engines now call `lib.admin.isClientAllowed(request)`, the helper-body coverage + a registration pin moved to `test/lib/admin.test.js`, and the cross-engine byte-identical sync-guard is retired (one source now). `isClientAllowed(req)` reads `process.gina._adminAllowList` internally (drop-in, zero `gna.js` change); an exported `_isAllowedWithList(req, list)` seam gives branch coverage without mutating the global. No behavior change (no changie).
|
|
953
|
+
|
|
954
|
+
193. **A settled HTTP/2 `self.query()` stream must be released at EVERY non-retry terminal, or its listeners strand the per-request controller + the `router.js` config clone until the cached session dies (dev-mode burst heap retention, #B52, 2026-06-18, commit `e4c274d2`).** `controller.js`'s `handleHTTP2ClientRequest`/`_sendRequest` installs stream listeners (`onStreamTimeout`/`onQueryError`/`onQueryClosed`/`onEnd`) that capture the caller's `callback` → `self` (the per-request controller) → `local.options.conf`, the large per-request config deep-clone made at `router.js:537` (`options.conf = JSON.clone(conf)`). On a NON-retry terminal the listeners were never detached, so the settled stream — held by the cached, TTL-less HTTP/2 session — stranded that controller + its conf clone until the session was finally torn down (~keepalive lifetime). In dev mode each request re-requires `controller.js` → a DISTINCT controller class+instance per request, so under sustained bursts the stranded clones pile up (measured on a minimal bundle: 300 req/7 s → ~512 MB live heap, then idle drains it; the leak is query-driven and render-AGNOSTIC — a JSON render + query leaked the same as a swig render + query, while a swig render without a query was flat — so it is NOT a render-delegate config leak). Prod is bounded (one reused controller class; the separate dev-mode module-children retention was #B32). Fixed with an idempotent `_finalizeStream()` helper (`_finalized` guard; `req.setTimeout(0)` cancels the 10 s stream timeout, `req.removeAllListeners()` drops the capturing listeners, a guarded `req.close()` releases the native stream; each op `try`/`catch`ed so cleanup never breaks the response path) called at all 5 non-retry terminals (timeout-exhausted / stream-error-nonretry / premature-close-exhausted / 502-exhausted / onEnd-success), placed BEFORE `_swallowIfNonCritical` so it runs on both the swallow-return and the callback/emit path. The RETRY branches do NOT finalize — they already `client.destroy()` the whole session, tearing the stream down; the 2 pre-flight PING swallow sites have no request stream yet. Measured: error-terminal spike +47→+7 MB/45 q (87 %; cached sessions 90→0); full-fix slope plateaus at +9.4 MB (bounded, conf-independent residual); burst 512 MB→25 MB (~95 %). `controller.js` is server-side (not in the browser bundle) → no dist rebuild. Rule: any non-retry terminal in an HTTP/2 client handler that leaves the stream alive on a cached/keepalive session retains everything the stream's listeners capture — detach the listeners + release the stream AT the terminal, not on eventual socket death. Tests: `controller.test.js §29`.
|
|
955
|
+
|
|
956
|
+
194. **The router's per-request config clone was narrowed from a whole-conf deep clone to only the mutated routing table, removing a dev/high-load heap high-water-mark proportional to config size (#B52-residual, 2026-06-18, commit `805afc9b`).** `router.js` `this.route` ran `options.conf = JSON.clone(conf)` on every matched request — a multi-MB deep clone of the ENTIRE bundle config (templates, server `coreConfiguration`, application assets), held by the per-request controller (`self._options.conf`) for its whole chained-query + render window; under sustained concurrency the in-flight clones pile into a heap high-water-mark that DRAINS on idle (a high-water-mark, not a leak — distinct from #B52, which retained the SAME clone via an unreleased query stream). An exhaustive audit (router + controller + render delegates + server + model + plugins + connectors + lib) found the ONLY subtree mutated THROUGH this clone is `conf.content.routing` (the `[rule].param` write on the next line); every other subtree is read-only on the per-request path — `setOptions` reassigns `conf.routing`/`reverseRouting`/`forms`/`locales`/`locale` WHOLESALE (a shallow top-level copy isolates those reassigns), and all plugins/connectors/model read config via their own `getConfig` clone or the global Config singleton, NEVER through `local.options.conf` (the only pass-outs of the clone — `getAssets` and the inspector config redactor — are read-only, verified). Fix: shallow-copy the top level + `conf.content`, deep-clone ONLY `conf.content.routing`; the large immutable remainder is shared by reference at zero per-request heap cost. Measured (minimal bundle, 150 concurrent slow requests, post-GC): peak 163 MB → 62 MB, drains to ~22 MB; data-identical output; 80/80 concurrent correctness; the saving scales with config size. `JSON.clone` unchanged; `router.js` is server-side (no dist rebuild). Rule: when a per-request object defensively deep-clones a large shared config, clone ONLY the subtrees actually mutated per request and share the immutable remainder by reference — but audit EVERY per-request writer first (a missed mutate-into a shared subtree reintroduces cross-request contamination). Tests: `router.test.js §11` (source pins + pure-logic replica incl. a subtract proving the routing deep-clone is load-bearing).
|
|
957
|
+
|
|
958
|
+
195. **`getRouteByUrl` aliased the shared route config's `param` by reference and rewrote its `:placeholder` fields in place, contaminating later requests for the same route — fixed by cloning the param subtree per request AND propagating the substituted param onto the returned route (#B52-residual finding-2, 2026-06-18, commit `e36b8e7c`).** `lib/routing/src/main.js` `getRouteByUrl` (reached server-side via `controller.js`'s redirect / relative-route resolution AND compiled into the browser bundle) built `params.param` as a BARE alias of `routing[name].param` while its sibling `middleware` was `JSON.clone`'d; the `routing` table there is `config.getRouting()` (server) / `gina.config.routing` (client) — both returned BY REFERENCE. The matcher (`fitsWithRequirements` / `checkRouteParams`) then rewrites `param.{path,namespace,file,title}` IN PLACE for routes carrying a `:placeholder` in those fields, mutating the shared singleton: request A's substitution strips the `:placeholder`, so request B to the same route fails the `/\:/` re-substitution guard and inherits A's resolved value (server cross-request leak; client stale-param across repeat navigations). The server main matcher (`server.js:4852`) and the cached fast-path (`getCached`) were already protected by their own clones — `getRouteByUrl` was the lone unprotected entry (its `must remain identical to server.js` invariant comment had drifted). Fix = TWO coordinated edits, NOT the one-line "clone param like middleware": (1) `param: JSON.clone(routing[name].param)` to stop aliasing; (2) `route.param = params.param` after `route = JSON.clone(routing[name])`, because `getRouteByUrl` returns a fresh clone of the singleton (NOT the mutated `params`) — cloning alone isolates the singleton but returns the un-substituted `:placeholder`, regressing even the FIRST request. Browser-bundled (`core/asset/plugin/src/vendor/gina/build.json` aliases `lib/routing` → `lib/routing/src/main`) → prod dist rebuilt (the 4 `gina.*` artifacts; baseline-build-zero-drift confirmed on the clean tree first). Rule: when a per-request matcher both (a) aliases a shared config object and (b) returns a re-clone of that shared object, isolating the alias alone is insufficient — the per-request mutations must ALSO be propagated onto the returned clone, or the result regresses while the singleton is merely spared. Deferred sibling (filed, not fixed): `route.middleware` is also re-cloned from the singleton, so any splice done on `params.middleware` is likewise dropped from the return — unmeasured, a separate future slice. Tests: `routing-fixes.test.js §04` (source pins on both edits + a two-request replica + a subtract proving the bare alias contaminates request 2 + a clone-only-without-propagation case proving the 2nd edit is load-bearing). Sibling of #194 — same routing-clone-correctness family; this was #194's deferred adjacent finding.
|
|
959
|
+
|
|
960
|
+
196. **The dev Inspector now binds to the opener tab via a per-tab `BroadcastChannel` (`?ch=<tabId>`), so its data tabs (Data/View/Forms/Query/Flow) track the page you opened it from instead of whichever render last touched the bundle-global channels (#INS15, 2026-06-18, commit `1d6e160d`).** When a bundle's pages send `Cross-Origin-Opener-Policy: same-origin` but the `/_gina/inspector/` route sends no COOP header, the COOP mismatch severs `window.opener` for the Inspector popup; with no opener the Inspector falls back to bundle-global DATA channels — the shared `localStorage.__ginaData` slot (every same-origin tab's statusbar writes it) and the worker-wide `/_gina/agent` passive SSE (carries EVERY render the worker handles, across all tabs + background JSON XHRs) — so the Query tab reflected whichever render last touched the shared state, not the page being viewed (intermittent "not refreshed from one page to another"; single-tab-no-background-activity → no clobber, hence intermittent; this is NOT the `_isStaleSource` pid guard, which needs a multi-worker bundle — a single-worker bundle has a constant `gina pid`). The obvious COOP-header fix (restore `window.opener`) is insufficient: the passive SSE runs in opener mode too (it exists because opener-polling misses in-tab XHR/pushState renders) and is bundle-wide, so it would re-import the cross-tab clobber. Fix is additive + gated on `?ch=` (no `?ch=` ⇒ today's exact behaviour; `?target=` agent mode keeps priority): the statusbar derives a stable `sessionStorage` tab id, opens the embedded Inspector with `?ch=<tabId>`, and publishes that tab's CURRENT `__ginaData` on `gina-inspector-<tabId>` at the three points it already writes localStorage (page load + `ginaToolbar.update()` + `restore()`, covering full-nav AND in-tab XHR/pushState), answering the Inspector's `{type:'request'}` handshake (BroadcastChannel does not replay); the Inspector's `setupBoundChannel(ch)` binds the channel, sets `source='broadcast'`, and `pollData` gains a `source==='broadcast'` branch reading `_bcLatest` (re-uses the existing apply path — no refactor, no test-pin churn) — the global source-acquisition (opener/localStorage/engine.io/passive-SSE-data) is skipped while server logs still arrive via `tryServerLogs()` (`/_gina/logs`). `BroadcastChannel` over a per-tab localStorage key: real-time (no 2 s poll lag) + no storage-key leak (keys outlive closed tabs); both are equally isolated — the load-bearing decision is per-tab scoping + SSE-data suppression. `statusbar.html` + `inspector.js` are copied to dist (no minification) → a prod rebuild touches only those two artifacts. Verified live end-to-end (bind via request/reply; a render in another tab + a cross-channel decoy ignored; opener-tab navigation followed; no console errors). Deferred follow-up: client console logs from the opener tab are also COOP-lost (`pollLogs` reads the null `window.opener.__ginaLogs`) — broadcastable on the same channel later. Rule: a diagnostic/Inspector channel that must track ONE page needs a per-tab transport — the opener binding (COOP-severable) and any bundle-wide localStorage/SSE channel are not page-scoped. Tests: `inspector.test.js §81`.
|
|
961
|
+
|
|
962
|
+
197. **Live-check error-MESSAGE visibility has three write paths; the steady-state one — the `data-gina-form-errors` "refresh" re-create — was made focus-aware so the message stays hidden while a field is typed in and is revealed on blur (#livecheck message-on-blur, 2026-06-19, commit `932fc077`).** The browser validator's `handleErrorsDisplay` writes the `form-item-error-message` div in THREE places — *create* (hidden vs shown, gated on `isWarning`), `refreshWarning`'s un-hide loop, and the **refresh re-create** (the `errAttr` / `data-gina-form-errors` branch) which REMOVES + RE-CREATES the div on every live-check re-validation. Because `data-gina-form-errors` is set on every browser validation and the refresh branch runs LAST in the live-check global pass (after `refreshWarning`), it owns the STEADY-STATE message visibility — so a fix that only guards `refreshWarning`'s un-hide is silently overridden (measured: zero visible effect live). The create path was already focus-correct via `isWarning`; only the refresh re-create lacked the guard. Fix: make the re-create focus-aware — create the message with class `form-item-error-message hidden` while the edited field is the active element (`document.activeElement && document.activeElement.name == name`), and `form-item-error-message` (shown) otherwise; on blur the field is no longer active, so the message is created shown (focusout commits `form-item-warning` -> `form-item-error`). Net behaviour: while typing only the soft `form-item-warning` border shows; the error message is revealed on blur/commit. `validator/src/main.js` is browser-bundled -> prod dist rebuilt (the 4 `gina.*` artifacts). Rule: when an error/message element is written by multiple paths in a single live-validation pass, the writer that runs LAST owns the steady state — guard THAT one, not an earlier writer it overrides. Tests: `test/core/validator-livecheck-message-blur.test.js` (focused-hides / blurred-shows / null-active-shows replica + a subtract reproducing the pre-fix always-shown bug + a source pin on the focus-aware re-create).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gina",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "Node.js MVC framework with built-in HTTP/2, multi-bundle architecture, and scope-based data isolation — no Express dependency",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nodejs",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
],
|
|
61
61
|
"copyright": "Copyright (c) 2009-2026 Rhinostone <contact@gina.io>",
|
|
62
62
|
"engine": {
|
|
63
|
-
"node": ">= 22 <
|
|
63
|
+
"node": ">= 22 <27"
|
|
64
64
|
},
|
|
65
65
|
"config": {
|
|
66
66
|
"optionalPrefix": "~/.npm-global",
|
|
@@ -72,12 +72,12 @@
|
|
|
72
72
|
"gina-container": "bin/gina-container",
|
|
73
73
|
"gina-init": "bin/gina-init"
|
|
74
74
|
},
|
|
75
|
-
"main": "./framework/v0.5.
|
|
75
|
+
"main": "./framework/v0.5.4/core/gna",
|
|
76
76
|
"exports": {
|
|
77
77
|
".": {
|
|
78
78
|
"types": "./types/index.d.ts",
|
|
79
79
|
"import": "./index.mjs",
|
|
80
|
-
"require": "./framework/v0.5.
|
|
80
|
+
"require": "./framework/v0.5.4/core/gna.js"
|
|
81
81
|
},
|
|
82
82
|
"./gna": {
|
|
83
83
|
"types": "./types/gna.d.ts",
|
package/framework/v0.5.3/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.5.3
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
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.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.css
RENAMED
|
File without changes
|
/package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.js
RENAMED
|
File without changes
|
/package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/beemaster/index.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/inspector/index.html
RENAMED
|
File without changes
|
/package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/inspector/inspector.css
RENAMED
|
File without changes
|
|
File without changes
|
/package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js
RENAMED
|
File without changes
|
/package/framework/{v0.5.3 → v0.5.4}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.br
RENAMED
|
File without changes
|
/package/framework/{v0.5.3 → v0.5.4}/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
|