gina 0.4.5 → 0.4.6
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 +36 -0
- package/CONTRIBUTING.md +2 -2
- package/README.md +10 -8
- package/ROADMAP.md +2 -2
- package/framework/v0.4.6/VERSION +1 -0
- package/framework/v0.4.6/core/asset/plugin/dist/vendor/gina/css/gina.min.css +1 -0
- package/framework/v0.4.6/core/asset/plugin/dist/vendor/gina/css/gina.min.css.br +0 -0
- package/framework/v0.4.6/core/asset/plugin/dist/vendor/gina/css/gina.min.css.gz +0 -0
- package/framework/{v0.4.5 → v0.4.6}/core/asset/plugin/dist/vendor/gina/inspector/inspector.js +62 -0
- package/framework/{v0.4.5 → v0.4.6}/core/asset/plugin/dist/vendor/gina/js/gina.js +934 -42
- package/framework/v0.4.6/core/asset/plugin/dist/vendor/gina/js/gina.min.js +571 -0
- package/framework/v0.4.6/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
- package/framework/v0.4.6/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
- package/framework/{v0.4.5 → v0.4.6}/core/controller/controller.js +62 -6
- package/framework/v0.4.6/core/controller/controller.render-nunjucks-async.js +788 -0
- package/framework/v0.4.6/core/controller/controller.render-swig-async.js +664 -0
- package/framework/{v0.4.5 → v0.4.6}/core/controller/controller.render-swig.js +52 -5
- package/framework/{v0.4.5 → v0.4.6}/core/gna.js +24 -0
- package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/csp/README.md +35 -0
- package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/csp/src/main.js +136 -2
- package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/storage/package.json +0 -3
- package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/validator/package.json +0 -3
- package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/validator/src/main.js +17 -4
- package/framework/{v0.4.5 → v0.4.6}/core/server.isaac.js +2 -2
- package/framework/{v0.4.5 → v0.4.6}/core/server.js +273 -97
- package/framework/{v0.4.5 → v0.4.6}/helpers/data/package.json +0 -3
- package/framework/{v0.4.5 → v0.4.6}/helpers/data/src/main.js +58 -3
- package/framework/{v0.4.5 → v0.4.6}/helpers/json/package.json +0 -3
- package/framework/{v0.4.5 → v0.4.6}/helpers/plugins/package.json +0 -3
- package/framework/{v0.4.5 → v0.4.6}/lib/archiver/package.json +0 -3
- package/framework/{v0.4.5 → v0.4.6}/lib/cache/package.json +0 -3
- package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/link.js +16 -5
- package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/msg.json +1 -1
- package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/restart.js +11 -3
- package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/start.js +5 -1
- package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/version.js +24 -3
- package/framework/{v0.4.5 → v0.4.6}/lib/cmd/helper.js +28 -9
- package/framework/{v0.4.5 → v0.4.6}/lib/cmd/project/add.js +29 -13
- package/framework/{v0.4.5 → v0.4.6}/lib/collection/package.json +0 -3
- package/framework/{v0.4.5 → v0.4.6}/lib/cron/package.json +0 -3
- package/framework/{v0.4.5 → v0.4.6}/lib/domain/package.json +0 -3
- package/framework/{v0.4.5 → v0.4.6}/lib/index.js +7 -0
- package/framework/{v0.4.5 → v0.4.6}/lib/inherits/package.json +0 -3
- package/framework/{v0.4.5 → v0.4.6}/lib/logger/package.json +0 -3
- package/framework/{v0.4.5 → v0.4.6}/lib/merge/package.json +0 -3
- package/framework/{v0.4.5 → v0.4.6}/lib/model.js +17 -0
- package/framework/{v0.4.5 → v0.4.6}/lib/nunjucks-filters/src/main.js +37 -11
- package/framework/{v0.4.5 → v0.4.6}/lib/routing/package.json +0 -3
- package/framework/{v0.4.5 → v0.4.6}/lib/routing/src/main.js +4 -4
- package/framework/{v0.4.5 → v0.4.6}/lib/swig-filters/package.json +0 -3
- package/framework/{v0.4.5 → v0.4.6}/lib/swig-filters/src/main.js +45 -6
- package/framework/v0.4.6/lib/template-loaders/package.json +17 -0
- package/framework/v0.4.6/lib/template-loaders/src/loaders/http.js +272 -0
- package/framework/v0.4.6/lib/template-loaders/src/loaders/memory.js +75 -0
- package/framework/v0.4.6/lib/template-loaders/src/main.js +134 -0
- package/framework/{v0.4.5 → v0.4.6}/package.json +2 -2
- package/gna.js +4 -4
- package/llms.txt +32 -44
- package/package.json +6 -3
- package/playwright.config.js +35 -0
- package/schema/settings.json +105 -0
- package/types/gna.d.ts +1 -1
- package/framework/v0.4.5/VERSION +0 -1
- package/framework/v0.4.5/core/asset/plugin/dist/vendor/gina/css/gina.min.css +0 -1
- package/framework/v0.4.5/core/asset/plugin/dist/vendor/gina/css/gina.min.css.br +0 -0
- package/framework/v0.4.5/core/asset/plugin/dist/vendor/gina/css/gina.min.css.gz +0 -0
- package/framework/v0.4.5/core/asset/plugin/dist/vendor/gina/js/gina.min.js +0 -555
- package/framework/v0.4.5/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
- package/framework/v0.4.5/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/AUTHORS +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/LICENSE +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/html/nolayout.html +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/html/static.html +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/img/android-chrome-192x192.png +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/img/android-chrome-512x512.png +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/img/apple-touch-icon.png +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/img/favicon-16x16.png +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/img/favicon-32x32.png +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/img/favicon.ico +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/plugin/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.css +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/plugin/dist/vendor/gina/beemaster/index.html +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/plugin/dist/vendor/gina/html/statusbar.html +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.br +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.gz +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/plugin/dist/vendor/gina/inspector/have_heart_one-webfont.woff2 +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/plugin/dist/vendor/gina/inspector/index.html +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/plugin/dist/vendor/gina/inspector/inspector.css +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/plugin/dist/vendor/gina/inspector/logo.svg +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.br +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.gz +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/config.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/ai/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/ai/lib/connector.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/couchbase/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/couchbase/lib/connector.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/couchbase/lib/connector.v3.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/couchbase/lib/connector.v4.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/couchbase/lib/n1ql.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/couchbase/lib/session-store.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/couchbase/lib/session-store.v3.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/couchbase/lib/session-store.v4.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/mongodb/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/mongodb/lib/connector.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/mongodb/lib/pipeline-loader.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/mongodb/lib/session-store.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/mysql/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/mysql/lib/connector.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/postgresql/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/postgresql/lib/connector.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/redis/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/redis/lib/session-store.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/scylladb/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/scylladb/lib/connector.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/scylladb/lib/session-store.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/sql-parser.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/sqlite/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/sqlite/lib/connector.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/connectors/sqlite/lib/session-store.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/content.encoding +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/controller/controller.framework.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/controller/controller.render-json.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/controller/controller.render-nunjucks.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/controller/controller.render-stream.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/controller/controller.render-v1.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/controller/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/controller/inspector-window-emit.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/deps/busboy-1.6.0/LICENSE +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/deps/busboy-1.6.0/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/deps/busboy-1.6.0/lib/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/deps/busboy-1.6.0/lib/types/multipart.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/deps/busboy-1.6.0/lib/types/urlencoded.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/deps/busboy-1.6.0/lib/utils.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/deps/busboy-1.6.0/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/deps/streamsearch-1.1.0/LICENSE +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/deps/streamsearch-1.1.0/lib/sbmh.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/deps/streamsearch-1.1.0/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/dev/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/dev/lib/class.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/dev/lib/factory.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/dev/lib/tools.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/locales/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/locales/currency.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/locales/dist/language/en.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/locales/dist/language/fr.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/locales/dist/region/en.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/locales/dist/region/fr.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/locales/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/mime.types +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/model/entity.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/model/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/model/template/entityFactory.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/model/template/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/csrf/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/csrf/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/csrf/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/coep/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/coep/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/coep/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/coop/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/coop/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/coop/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/corp/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/corp/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/corp/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/csp/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/hide-powered-by/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/hide-powered-by/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/hide-powered-by/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/hsts/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/hsts/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/hsts/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/origin-agent-cluster/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/origin-agent-cluster/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/origin-agent-cluster/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/referrer-policy/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/referrer-policy/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/referrer-policy/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-content-type-options/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-content-type-options/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-content-type-options/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-dns-prefetch-control/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-dns-prefetch-control/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-dns-prefetch-control/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-download-options/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-download-options/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-download-options/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-frame-options/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-frame-options/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-frame-options/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-xss-protection/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-xss-protection/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/security-headers/x-xss-protection/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/session/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/session/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/session/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/storage/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/storage/build.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/storage/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/validator/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/validator/build.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/plugins/lib/validator/src/form-validator.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/router.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/server.express.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/status.codes +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/_gitignore +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle/config/app.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle/config/connectors.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle/config/routing.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle/config/settings.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle/config/settings.server.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle/config/templates.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle/config/watchers.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle/controllers/controller.content.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle/controllers/controller.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle/controllers/setup.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle/locales/en.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle_namespace/controllers/controller.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle_public/css/default.css +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle_public/css/home.css +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle_public/css/vendor/readme.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle_public/favicon.ico +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle_public/js/vendor/readme.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle_public/manifest.webmanifest +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle_public/readme.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle_public/sw.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle_templates/handlers/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle_templates/html/content/homepage.html +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle_templates/html/includes/error-msg-noscript.html +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle_templates/html/includes/error-msg-outdated-browser.html +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/boilerplate/bundle_templates/html/layouts/main.html +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/command/gina.bat.tpl +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/command/gina.tpl +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/conf/env.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/conf/manifest.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/conf/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/conf/settings.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/conf/statics.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/conf/templates.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/error/client/json/401.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/error/client/json/403.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/error/client/json/404.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/error/server/html/50x.html +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/error/server/json/500.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/error/server/json/503.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/core/template/extensions/logger/config.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/helpers/console.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/helpers/context.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/helpers/data/LICENSE +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/helpers/data/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/helpers/dateFormat.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/helpers/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/helpers/json/LICENSE +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/helpers/json/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/helpers/json/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/helpers/path.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/helpers/plugins/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/helpers/plugins/src/api-error.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/helpers/plugins/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/helpers/prototypes.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/helpers/task.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/helpers/text.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/archiver/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/archiver/build.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/archiver/src/dep/jszip.min.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/archiver/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/async/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/async/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cache/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cache/build.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cache/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/aliases.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/add.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/arguments.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/build.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/copy.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/cp.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/help.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/help.txt +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/inc/name-rewrite.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/list.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/mcp-start.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/mcp.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/oas.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/openapi.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/remove.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/rename.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/restart.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/rm.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/start.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/status.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/bundle/stop.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/cache/stats.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/connector/add.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/connector/arguments.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/connector/help.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/connector/help.txt +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/connector/list.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/connector/migrate.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/connector/remove.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/connector/rm.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/env/add.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/env/get.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/env/help.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/env/help.txt +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/env/link-dev.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/env/list.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/env/remove.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/env/rm.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/env/set.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/env/unset.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/env/use.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/arguments.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/build.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/dot.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/get.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/help.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/help.txt +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/init.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/link-node-modules.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/open.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/set.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/status.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/stop.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/tail.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/framework/update.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/gina-dev.1.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/gina-framework.1.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/gina.1.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/i18n/add.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/i18n/arguments.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/i18n/export.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/i18n/help.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/i18n/help.txt +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/i18n/import.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/i18n/scan.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/inspector/help.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/inspector/help.txt +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/inspector/open.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/minion/arguments.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/minion/help.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/minion/help.txt +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/minion/kill.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/minion/list.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/msg.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/port/help.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/port/help.txt +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/port/inc/scan.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/port/list.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/port/reset.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/port/set.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/project/arguments.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/project/build.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/project/help.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/project/help.txt +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/project/import.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/project/list.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/project/move.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/project/remove.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/project/rename.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/project/restart.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/project/rm.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/project/start.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/project/status.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/project/stop.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/protocol/arguments.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/protocol/help.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/protocol/help.txt +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/protocol/list.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/protocol/remove.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/protocol/set.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/scope/add.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/scope/help.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/scope/help.txt +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/scope/link-local.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/scope/link-production.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/scope/list.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/scope/remove.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/scope/rm.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/scope/use.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/secrets/arguments.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/secrets/check.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/secrets/help.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/secrets/help.txt +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/secrets/scan.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/service/help.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/service/help.txt +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/service/list.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/service/start.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd/view/add.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd-status-format/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cmd-status-format/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/collection/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/collection/build.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/collection/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/config.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/connector-registry/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/connector-registry/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cron/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/cron/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/domain/LICENSE +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/domain/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/domain/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/generator/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/i18n/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/i18n/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/inherits/LICENSE +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/inherits/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/inherits/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/inspector-redact/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/inspector-redact/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/instrument/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/instrument/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/job/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/job/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/logger/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/logger/src/containers/default/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/logger/src/containers/file/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/logger/src/containers/file/lib/logrotator/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/logger/src/containers/file/lib/logrotator/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/logger/src/containers/mq/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/logger/src/containers/mq/listener.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/logger/src/containers/mq/speaker.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/logger/src/helper.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/logger/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/math/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/mcp-dispatch/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/mcp-dispatch/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/mcp-http/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/mcp-http/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/mcp-server/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/mcp-server/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/merge/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/merge/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/metrics/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/metrics/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/nunjucks-filters/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/nunjucks-filters/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/nunjucks-resolver/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/nunjucks-resolver/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/proc.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/routing/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/routing/build.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/routing/src/radix.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/routing-introspect/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/routing-introspect/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/secrets/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/secrets/src/backends/env.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/secrets/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/session-store.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/shell.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/state.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/swig-filters/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/swig-resolver/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/swig-resolver/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/url/README.md +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/url/index.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/url/routing.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/uuid/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/uuid/src/main.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/validator.js +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/watcher/package.json +0 -0
- /package/framework/{v0.4.5 → v0.4.6}/lib/watcher/src/main.js +0 -0
|
@@ -0,0 +1,788 @@
|
|
|
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 controller.render-nunjucks-async
|
|
11
|
+
* @description Render delegate for nunjucks bundles configured with a custom
|
|
12
|
+
* async template loader (`settings.template.nunjucks.loader`). controller.js
|
|
13
|
+
* selects this delegate when
|
|
14
|
+
* `process.gina._nunjucksLoaders[<templateRoot>].loader.async === true`; every
|
|
15
|
+
* other nunjucks bundle keeps the cached-Environment filesystem path
|
|
16
|
+
* (controller.render-nunjucks.js).
|
|
17
|
+
*
|
|
18
|
+
* Unlike render-nunjucks.js — which reads templates from disk through a cached
|
|
19
|
+
* `new nunjucks.FileSystemLoader(root)` Environment — this delegate renders
|
|
20
|
+
* through a PER-REQUEST `new nunjucks.Environment(adapter)` whose adapter is a
|
|
21
|
+
* `nunjucks.Loader.extend({ async, resolve, getSource })` subclass wrapping the
|
|
22
|
+
* gina async loader. nunjucks' async codegen drives `resolve -> getSource` for
|
|
23
|
+
* the page template AND its whole transitive `extends` / `include` / `import`
|
|
24
|
+
* chain through the custom loader, so templates can live off-disk (remote / CDN
|
|
25
|
+
* / object-storage / in-memory). The gina loader's CVE-2023-25345 guard runs on
|
|
26
|
+
* every hop (inside `getSource`'s `ginaLoader.resolve`).
|
|
27
|
+
*
|
|
28
|
+
* ## Per-request context via process.gina._renderALS (#B25 / #TPL1 Tier-2)
|
|
29
|
+
*
|
|
30
|
+
* The context-bearing gina filters (getUrl / getWebroot / t / tIcu) read their
|
|
31
|
+
* per-request context from a process-global singleton (`NunjucksFilters.instance
|
|
32
|
+
* ._options`) that every `NunjucksFilters({…})` call overwrites. The SYNC
|
|
33
|
+
* delegate (render-nunjucks.js) is safe only because its render is synchronous —
|
|
34
|
+
* no other request runs between the factory call and the render, so the
|
|
35
|
+
* singleton is stable. An ASYNC `env.render` yields (awaited callback form), so a
|
|
36
|
+
* concurrent request can stomp the singleton between `addFilter` and the filter
|
|
37
|
+
* invocation — a cross-request context bleed (#B25). A per-request Environment
|
|
38
|
+
* does NOT fix this: it isolates the filter name→function TABLE, not the
|
|
39
|
+
* singleton the functions read. (This corrects the original Slice-3 rationale,
|
|
40
|
+
* which mis-attributed the sync-path safety to the per-request env.)
|
|
41
|
+
*
|
|
42
|
+
* The fix (this slice): the gina filters are context-free — they read the
|
|
43
|
+
* per-request context from `process.gina._renderALS` at CALL time — and the
|
|
44
|
+
* render is wrapped in `_renderALS.run({ options, isProxyHost, throwError, req,
|
|
45
|
+
* res }, …)`. ALS propagates the store across every await in the render, so
|
|
46
|
+
* interleaved async renders each read their own context. This wrap is
|
|
47
|
+
* UNCONDITIONAL (it closes #B25 whether or not the compiled cache is opted in).
|
|
48
|
+
*
|
|
49
|
+
* Tier-2 compiled-template reuse is then opt-in via
|
|
50
|
+
* `settings.template.nunjucks.loader.cache` (dev-disabled): ON shares a
|
|
51
|
+
* per-bundle Environment on `process.gina._nunjucksAsyncEnvs` (its loader.cache
|
|
52
|
+
* populates across requests); OFF builds a fresh Environment per request (still
|
|
53
|
+
* race-safe via the unconditional `.run()`). EITHER mode keeps a SEPARATE
|
|
54
|
+
* registry from the sync delegate's filesystem `_nunjucksEnvs` (whose loader is a
|
|
55
|
+
* FileSystemLoader, not the gina async adapter).
|
|
56
|
+
*
|
|
57
|
+
* ## Callback-form render is mandatory
|
|
58
|
+
*
|
|
59
|
+
* With an async loader, a synchronous `env.render(name, ctx)` on an uncached
|
|
60
|
+
* template returns `null` silently (worse than throwing). The delegate therefore
|
|
61
|
+
* promisifies the callback form `env.render(name, ctx, cb)`.
|
|
62
|
+
*
|
|
63
|
+
* MVP scope (matches controller.render-swig-async.js): per-request env + loader
|
|
64
|
+
* adapter + gina filter registration + render + HTTP/1.1 & HTTP/2 send + post-
|
|
65
|
+
* render asset injection (the gina client bundle / CSS / JS via injectAssets()
|
|
66
|
+
* plus the gina-bootstrap whisper pass) + error-interception, so an off-disk
|
|
67
|
+
* full page ships the client runtime and is production-usable. Deferred to a
|
|
68
|
+
* follow-up slice (mirroring the swig-async deferral, all present in the sync
|
|
69
|
+
* render-nunjucks.js to port later): Inspector dev-payload, the bundle
|
|
70
|
+
* `controllers/setup.js` `this.engine` filter hook (registerUserFilters — the
|
|
71
|
+
* per-request env makes its once-per-env `_userSetupDone` marker moot), static
|
|
72
|
+
* HTML cache writes (writeCache), error-template routing (isRenderingCustomError
|
|
73
|
+
* + renderString), the Flow-timeline late entries, and Early Hints.
|
|
74
|
+
*
|
|
75
|
+
* @package gina.framework
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
// libRef via the registry with a require.cache fallback: server.isaac.js
|
|
79
|
+
// refreshCore() overwrites the lib cache entry with the exports value (not a
|
|
80
|
+
// Module object) in dev mode, so a plain require() can return undefined and
|
|
81
|
+
// crash the module-level read. Mirrors render-nunjucks.js / render-swig-async.js.
|
|
82
|
+
const libRef = require('./../../lib') || require.cache[require.resolve('./../../lib')];
|
|
83
|
+
const merge = libRef.merge;
|
|
84
|
+
// Collection — filters the asset list to common-only when rendering without a
|
|
85
|
+
// layout (isWithoutLayout XHR/popin responses), mirroring render-nunjucks.js /
|
|
86
|
+
// render-swig.js.
|
|
87
|
+
const Collection = libRef.Collection;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Lazily construct the process-wide render-context AsyncLocalStorage, parked on
|
|
91
|
+
* `process.gina` so it survives dev-mode `require.cache` eviction of this
|
|
92
|
+
* delegate (mirrors `process.gina._reqALS` / `_queryALS`). The render is wrapped
|
|
93
|
+
* in `_renderALS.run({ options, isProxyHost, throwError, req, res }, …)` so the
|
|
94
|
+
* context-free gina filters (getUrl/getWebroot/t/tIcu) read the right request's
|
|
95
|
+
* context at call time — closing the #B25 singleton race and enabling the opt-in
|
|
96
|
+
* shared-env compiled-template cache (#TPL1 Tier-2).
|
|
97
|
+
*
|
|
98
|
+
* @inner
|
|
99
|
+
* @returns {AsyncLocalStorage} the shared render-context store
|
|
100
|
+
*/
|
|
101
|
+
function getRenderALS() {
|
|
102
|
+
if (!process.gina._renderALS) {
|
|
103
|
+
var AsyncLocalStorage = require('async_hooks').AsyncLocalStorage;
|
|
104
|
+
process.gina._renderALS = new AsyncLocalStorage();
|
|
105
|
+
}
|
|
106
|
+
return process.gina._renderALS;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Resolve the loader identifier for the page template, relative to the bundle
|
|
111
|
+
* template root. Same shape as render-nunjucks.js `resolveTemplatePath()`:
|
|
112
|
+
* honours a `self.setTemplate()` override, the namespace sub-directory (dropping
|
|
113
|
+
* a redundant `<namespace>-` prefix), and the extension append. No CVE path
|
|
114
|
+
* check here — the gina loader's `resolve()` guards every hop.
|
|
115
|
+
*
|
|
116
|
+
* @inner
|
|
117
|
+
* @param {object} data - Template data (`data.page.view.file` / `.ext`)
|
|
118
|
+
* @param {object} localOptions - Controller options (`.namespace`, `._templateOverride`)
|
|
119
|
+
* @returns {string} Loader identifier (path relative to the template root)
|
|
120
|
+
*/
|
|
121
|
+
function resolveTemplatePath(data, localOptions) {
|
|
122
|
+
// Runtime override from self.setTemplate(file, ext) fully replaces the
|
|
123
|
+
// rule's default path (no namespace prefixing).
|
|
124
|
+
if (localOptions && localOptions._templateOverride && localOptions._templateOverride.file) {
|
|
125
|
+
var ovFile = localOptions._templateOverride.file;
|
|
126
|
+
var ovExt = localOptions._templateOverride.ext || data.page.view.ext || '';
|
|
127
|
+
if (ovExt && !ovFile.endsWith(ovExt)) { ovFile += ovExt; }
|
|
128
|
+
return ovFile;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
var file = data.page.view.file;
|
|
132
|
+
var ext = data.page.view.ext || '';
|
|
133
|
+
|
|
134
|
+
if (localOptions.namespace) {
|
|
135
|
+
var effective = file || localOptions.namespace;
|
|
136
|
+
if (effective === localOptions.namespace) { effective = 'index'; }
|
|
137
|
+
// Drop a redundant `<namespace>-` prefix from the file segment so a
|
|
138
|
+
// route named `<namespace>-<action>` resolves to `<namespace>/<action>`.
|
|
139
|
+
var nsPrefix = localOptions.namespace + '-';
|
|
140
|
+
if (effective.length > nsPrefix.length && effective.indexOf(nsPrefix) === 0) {
|
|
141
|
+
effective = effective.substring(nsPrefix.length);
|
|
142
|
+
}
|
|
143
|
+
var rel = localOptions.namespace + '/' + effective;
|
|
144
|
+
if (ext && !rel.endsWith(ext)) { rel += ext; }
|
|
145
|
+
return rel;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
var relRoot = file;
|
|
149
|
+
if (ext && !relRoot.endsWith(ext)) { relRoot += ext; }
|
|
150
|
+
return relRoot;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Compute the per-request proxy-host decision from the raw request headers and
|
|
155
|
+
* the resolved bundle options. Extracted so the render path can stash it in the
|
|
156
|
+
* `_renderALS` store (the gina filters read `ctx.isProxyHost` from there).
|
|
157
|
+
* Mirrors the isProxyHost derivation in render-nunjucks.js / render-swig.js.
|
|
158
|
+
*
|
|
159
|
+
* @inner
|
|
160
|
+
* @param {object} req - Request (raw headers)
|
|
161
|
+
* @param {object} localOptions - Controller options (`.conf`, hostname/port)
|
|
162
|
+
* @returns {boolean} true when the request appears to arrive via a reverse proxy
|
|
163
|
+
*/
|
|
164
|
+
function computeIsProxyHost(req, localOptions) {
|
|
165
|
+
var localRequestPort = req.headers.port || req.headers[':port'];
|
|
166
|
+
return (
|
|
167
|
+
typeof(req.headers.host) != 'undefined'
|
|
168
|
+
&& typeof(localRequestPort) != 'undefined'
|
|
169
|
+
&& (localRequestPort === '80' || localRequestPort === '443' || localRequestPort === 80 || localRequestPort === 443)
|
|
170
|
+
&& localOptions.conf.server.scheme +'://'+ req.headers.host+':'+ localRequestPort != localOptions.conf.hostname.replace(/\:\d+$/, '') +':'+ localOptions.conf.server.port
|
|
171
|
+
||
|
|
172
|
+
typeof(req.headers[':authority']) != 'undefined'
|
|
173
|
+
&& localOptions.conf.server.scheme +'://'+ req.headers[':authority'] != localOptions.conf.hostname
|
|
174
|
+
||
|
|
175
|
+
typeof(req.headers.host) != 'undefined'
|
|
176
|
+
&& typeof(localRequestPort) != 'undefined'
|
|
177
|
+
&& (localRequestPort === '80' || localRequestPort === '443' || localRequestPort === 80 || localRequestPort === 443)
|
|
178
|
+
&& req.headers.host == localOptions.conf.host
|
|
179
|
+
||
|
|
180
|
+
typeof(req.headers['x-nginx-proxy']) != 'undefined'
|
|
181
|
+
&& String(req.headers['x-nginx-proxy']).toLowerCase() === 'true'
|
|
182
|
+
||
|
|
183
|
+
typeof(process.gina) != 'undefined' && typeof(process.gina.PROXY_HOSTNAME) != 'undefined'
|
|
184
|
+
) ? true : false;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Register gina's NunjucksFilters on a nunjucks Environment. The filters are
|
|
189
|
+
* context-free: getUrl / getWebroot / t / tIcu read per-request context from
|
|
190
|
+
* `process.gina._renderALS` at call time, so a single shared filter table can't
|
|
191
|
+
* bleed one request's context into another's interleaved async render (#B25).
|
|
192
|
+
* The build-time conf is therefore empty — everything flows through the ALS store
|
|
193
|
+
* stamped by the render `.run()` wrap. Called once on a shared env (cache on) or
|
|
194
|
+
* per request on a fresh env (cache off). Bundle-level filter wraps registered on
|
|
195
|
+
* `process.gina._bundleFilterWraps` are applied here, parity with the sync
|
|
196
|
+
* render-nunjucks.js path.
|
|
197
|
+
*
|
|
198
|
+
* @inner
|
|
199
|
+
* @param {*} env - The `nunjucks.Environment` to extend
|
|
200
|
+
* @param {function} nunjucksFilters - The NunjucksFilters factory (registry/require)
|
|
201
|
+
* @param {function} throwError - `self.throwError`, carried for the singleton-fallback path
|
|
202
|
+
* @returns {void}
|
|
203
|
+
*/
|
|
204
|
+
function registerGinaFilters(env, nunjucksFilters, throwError) {
|
|
205
|
+
var filters = nunjucksFilters({ options: {}, isProxyHost: false, throwError: throwError });
|
|
206
|
+
|
|
207
|
+
// Apply bundle-level filter wraps registered on process state. Bundle-level
|
|
208
|
+
// monkey-patches on `lib.nunjucksFilters` don't survive refreshCore() (a
|
|
209
|
+
// fresh lib singleton ~per-request in dev mode), so bundles register their
|
|
210
|
+
// wrap on `process.gina._bundleFilterWraps[bundleName]` and the framework
|
|
211
|
+
// applies them here — parity with the sync render-nunjucks.js path.
|
|
212
|
+
var bundleFilterWraps = (process.gina && process.gina._bundleFilterWraps) || {};
|
|
213
|
+
Object.keys(bundleFilterWraps).forEach(function (bundleName) {
|
|
214
|
+
var wrap = bundleFilterWraps[bundleName];
|
|
215
|
+
if (typeof wrap === 'function') {
|
|
216
|
+
try {
|
|
217
|
+
filters = wrap(filters) || filters;
|
|
218
|
+
} catch (wrapErr) {
|
|
219
|
+
try {
|
|
220
|
+
console.warn('[render-nunjucks-async] bundle filter wrap failed for ' + bundleName + ': ' + (wrapErr.message || wrapErr));
|
|
221
|
+
} catch (e) {}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
for (var name in filters) {
|
|
227
|
+
if (typeof filters[name] === 'function' && name !== 'getConfig') {
|
|
228
|
+
env.addFilter(name, filters[name]);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Send the rendered HTML, covering HEAD + HTTP/2 stream + HTTP/1.1 in the
|
|
235
|
+
* four-way branch from class.controller.md §7b. Ported verbatim from
|
|
236
|
+
* render-nunjucks.js `sendHtmlResponse()` (the proven separate-delegate send).
|
|
237
|
+
*
|
|
238
|
+
* @inner
|
|
239
|
+
* @param {object} local - Per-request closure (for `_trailers`)
|
|
240
|
+
* @param {string} html - Final HTML string
|
|
241
|
+
* @param {object} req - Request (captured)
|
|
242
|
+
* @param {object} res - Response (captured)
|
|
243
|
+
* @returns {void}
|
|
244
|
+
*/
|
|
245
|
+
function sendHtmlResponse(local, html, req, res) {
|
|
246
|
+
if (res.headersSent) { return; }
|
|
247
|
+
|
|
248
|
+
var statusCode = res.statusCode || 200;
|
|
249
|
+
var stream = (res && typeof res.stream !== 'undefined') ? res.stream : null;
|
|
250
|
+
var isHead = /^HEAD$/i.test(req.method);
|
|
251
|
+
// #H10 — opt-in HTTP/2 response trailers (registered via self.sendTrailers()).
|
|
252
|
+
var _trailers = (local && local._trailers && typeof(local._trailers) === 'object') ? local._trailers : null;
|
|
253
|
+
var byteLength = Buffer.byteLength(html, 'utf8');
|
|
254
|
+
|
|
255
|
+
if (!res.getHeader('content-type')) {
|
|
256
|
+
res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (isHead) {
|
|
260
|
+
if (stream) {
|
|
261
|
+
// Case 1: HEAD + HTTP/2
|
|
262
|
+
if (stream.destroyed || stream.closed) {
|
|
263
|
+
try { console.warn('[render-nunjucks-async] stream already destroyed on HEAD — client disconnected ('+ req.url +')'); } catch (e) {}
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
if (!stream.headersSent) {
|
|
267
|
+
var _headH2 = {
|
|
268
|
+
'content-type': res.getHeader('content-type'),
|
|
269
|
+
'content-length': byteLength,
|
|
270
|
+
':status': statusCode
|
|
271
|
+
};
|
|
272
|
+
var _pendingHeadH2 = res.getHeaders ? res.getHeaders() : {};
|
|
273
|
+
for (var _hh2k in _pendingHeadH2) {
|
|
274
|
+
if (!(_hh2k in _headH2)) { _headH2[_hh2k] = _pendingHeadH2[_hh2k]; }
|
|
275
|
+
}
|
|
276
|
+
stream.respond(_headH2);
|
|
277
|
+
}
|
|
278
|
+
stream.end();
|
|
279
|
+
res.headersSent = true;
|
|
280
|
+
} else {
|
|
281
|
+
// Case 2: HEAD + HTTP/1.1
|
|
282
|
+
res.setHeader('content-length', byteLength);
|
|
283
|
+
res.writeHead(statusCode);
|
|
284
|
+
res.end();
|
|
285
|
+
}
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (stream) {
|
|
290
|
+
// Case 3: body + HTTP/2
|
|
291
|
+
if (stream.destroyed || stream.closed) {
|
|
292
|
+
try { console.warn('[render-nunjucks-async] stream already destroyed — client disconnected before response ('+ req.url +')'); } catch (e) {}
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
if (!stream.headersSent) {
|
|
296
|
+
var _streamHeaders = {
|
|
297
|
+
'content-type': res.getHeader('content-type'),
|
|
298
|
+
':status': statusCode
|
|
299
|
+
};
|
|
300
|
+
var _pendingHeaders = res.getHeaders ? res.getHeaders() : {};
|
|
301
|
+
for (var _shk in _pendingHeaders) {
|
|
302
|
+
if (!(_shk in _streamHeaders)) { _streamHeaders[_shk] = _pendingHeaders[_shk]; }
|
|
303
|
+
}
|
|
304
|
+
if (_trailers) {
|
|
305
|
+
stream.once('wantTrailers', function() {
|
|
306
|
+
try { if (!stream.destroyed && !stream.closed) stream.sendTrailers(_trailers); } catch (_e) { /* best-effort */ }
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
stream.respond(_streamHeaders, _trailers ? { waitForTrailers: true } : undefined);
|
|
310
|
+
}
|
|
311
|
+
stream.end(html);
|
|
312
|
+
res.headersSent = true;
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Case 4: body + HTTP/1.1
|
|
317
|
+
res.writeHead(statusCode);
|
|
318
|
+
res.end(html);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Post-render asset injection. Inserts the bundle's stylesheets / scripts, the
|
|
323
|
+
* external plugins, and the gina client bootstrap (`gina.onload.min.js`) onto
|
|
324
|
+
* the `</head>` / `</body>` anchors of the rendered HTML. Verbatim port of
|
|
325
|
+
* render-nunjucks.js `injectAssets()` — the async delegate renders through the
|
|
326
|
+
* engine API (no FS `getAssets()` machinery), so it injects post-render.
|
|
327
|
+
*
|
|
328
|
+
* Honours `javascriptsDeferEnabled` (scripts in `<head>` vs before `</body>`)
|
|
329
|
+
* and `javascriptsExcluded === '**'` (suppresses the bootstrap). Skips any
|
|
330
|
+
* asset already present in the HTML (idempotent) and any fragment missing the
|
|
331
|
+
* `</head>`/`</body>` anchor (HEAD responses, partial renders) — returning the
|
|
332
|
+
* HTML unchanged rather than growing truncated markup.
|
|
333
|
+
*
|
|
334
|
+
* @inner
|
|
335
|
+
* @param {string} html - Rendered HTML from the nunjucks async engine
|
|
336
|
+
* @param {object} data - Template data (`data.page.view.stylesheets`/`.scripts`)
|
|
337
|
+
* @param {object} localOptions - Controller options (`template.ginaLoader`, `.externalPlugins`, …)
|
|
338
|
+
* @param {string} [cspNonce] - #HDR5 per-request CSP nonce; stamps the bootstrap <script>
|
|
339
|
+
* @returns {string} HTML with asset tags injected where appropriate
|
|
340
|
+
*/
|
|
341
|
+
function injectAssets(html, data, localOptions, cspNonce) {
|
|
342
|
+
if (typeof html !== 'string' || html.length === 0) { return html; }
|
|
343
|
+
if (!data || !data.page || !data.page.view) { return html; }
|
|
344
|
+
|
|
345
|
+
var stylesheetsHtml = data.page.view.stylesheets || '';
|
|
346
|
+
var scriptsHtml = data.page.view.scripts || '';
|
|
347
|
+
var tpl = localOptions && localOptions.template;
|
|
348
|
+
var isDeferMode = !!(tpl && tpl.javascriptsDeferEnabled);
|
|
349
|
+
var jsExcluded = tpl && tpl.javascriptsExcluded;
|
|
350
|
+
var ginaLoader = tpl && tpl.ginaLoader;
|
|
351
|
+
// #HDR5 — stamp the bootstrap <script> with the per-request nonce when present.
|
|
352
|
+
// The loader is a cached, immutable string; .replace() returns a fresh copy.
|
|
353
|
+
if (cspNonce && typeof ginaLoader === 'string') {
|
|
354
|
+
ginaLoader = ginaLoader.replace(
|
|
355
|
+
'<script type="text/javascript">',
|
|
356
|
+
'<script type="text/javascript" nonce="' + cspNonce + '">'
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
var externalPlugins = (tpl && Array.isArray(tpl.externalPlugins)) ? tpl.externalPlugins : [];
|
|
360
|
+
var hasHead = /<\/head>/i.test(html);
|
|
361
|
+
var hasBody = /<\/body>/i.test(html);
|
|
362
|
+
|
|
363
|
+
if (stylesheetsHtml && hasHead && html.indexOf(stylesheetsHtml) === -1) {
|
|
364
|
+
html = html.replace(/<\/head>/i, '\n\t' + stylesheetsHtml + '\n</head>');
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (scriptsHtml && html.indexOf(scriptsHtml) === -1) {
|
|
368
|
+
if (isDeferMode && hasHead) {
|
|
369
|
+
html = html.replace(/<\/head>/i, '\t' + scriptsHtml + '\n</head>');
|
|
370
|
+
} else if (hasBody) {
|
|
371
|
+
html = html.replace(/<\/body>/i, '\t' + scriptsHtml + '\n</body>');
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (externalPlugins.length > 0 && hasHead) {
|
|
376
|
+
var extHtml = externalPlugins.join('');
|
|
377
|
+
if (extHtml && html.indexOf(extHtml) === -1) {
|
|
378
|
+
html = html.replace(/<\/head>/i, '\t' + extHtml + '\n</head>');
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
if (
|
|
383
|
+
ginaLoader
|
|
384
|
+
&& jsExcluded !== '**'
|
|
385
|
+
&& hasHead
|
|
386
|
+
&& !/window\.onGinaLoaded/.test(html)
|
|
387
|
+
) {
|
|
388
|
+
html = html.replace(/<\/head>/i, '\t' + ginaLoader + '\n</head>');
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
return html;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Build the per-request async loader adapter — a `nunjucks.Loader.extend(...)`
|
|
396
|
+
* subclass instance that bridges nunjucks' loader protocol to the gina async
|
|
397
|
+
* loader. `resolve` is overridden to identity so the gina loader's `resolve()`
|
|
398
|
+
* (carrying the CVE-2023-25345 segment guard + any backend containment check)
|
|
399
|
+
* is the single path authority on every transitive hop; nunjucks' default
|
|
400
|
+
* `resolve` would path-join `..`-laden ids. `getSource` routes through
|
|
401
|
+
* `ginaLoader.resolve` then `ginaLoader.load`, returning the nunjucks
|
|
402
|
+
* `{ src, path, noCache }` source shape.
|
|
403
|
+
*
|
|
404
|
+
* @inner
|
|
405
|
+
* @param {*} nunjucks - The resolved nunjucks module (exposes `.Loader`)
|
|
406
|
+
* @param {object} ginaLoader - Guarded async loader (from `process.gina._nunjucksLoaders`)
|
|
407
|
+
* @returns {*} A new async loader adapter instance for `new nunjucks.Environment(adapter)`
|
|
408
|
+
*/
|
|
409
|
+
function buildLoaderAdapter(nunjucks, ginaLoader) {
|
|
410
|
+
var AsyncGinaLoader = nunjucks.Loader.extend({
|
|
411
|
+
async: true,
|
|
412
|
+
// Identity: hand the raw requested name to getSource so gina's
|
|
413
|
+
// flat-namespace resolve() is the only path authority.
|
|
414
|
+
resolve: function (from, to) { return to; },
|
|
415
|
+
getSource: function (name, cb) {
|
|
416
|
+
var id;
|
|
417
|
+
try {
|
|
418
|
+
id = ginaLoader.resolve(name); // CVE guard + backend containment run HERE
|
|
419
|
+
} catch (e) {
|
|
420
|
+
return void cb(e);
|
|
421
|
+
}
|
|
422
|
+
ginaLoader.load(id, function (err, src) {
|
|
423
|
+
if (err) { return void cb(err); }
|
|
424
|
+
cb(null, {
|
|
425
|
+
src: src,
|
|
426
|
+
path: id,
|
|
427
|
+
noCache: process.env.NODE_ENV_IS_DEV === 'true'
|
|
428
|
+
});
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
return new AsyncGinaLoader();
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Shared per-bundle nunjucks Environment for the Tier-2 compiled-template cache
|
|
437
|
+
* (opt-in `settings.template.nunjucks.loader.cache`, prod only). Unlike the
|
|
438
|
+
* cache-off path's fresh-per-request env, this env is built ONCE and reused, so
|
|
439
|
+
* nunjucks' loader.cache populates across requests (the adapter's getSource
|
|
440
|
+
* returns noCache:false outside dev). The gina filters are registered once on it
|
|
441
|
+
* (context-free; per-request context flows via process.gina._renderALS).
|
|
442
|
+
*
|
|
443
|
+
* SEPARATE registry from the sync delegate's `_nunjucksEnvs` (whose loader is a
|
|
444
|
+
* FileSystemLoader, not the gina async adapter). Owner-guarded on
|
|
445
|
+
* `_nunjucksAsyncEnvsOwner !== nunjucks` so a dev-mode nunjucks hot-swap drops the
|
|
446
|
+
* cached envs (mirrors render-nunjucks.js `_nunjucksEnvsOwner`).
|
|
447
|
+
*
|
|
448
|
+
* @inner
|
|
449
|
+
* @param {*} nunjucks - The resolved nunjucks module (`.Environment`/`.Loader`)
|
|
450
|
+
* @param {string} templateRoot - Registry key (bundle template root)
|
|
451
|
+
* @param {object} ginaLoader - Guarded async loader (from `process.gina._nunjucksLoaders`)
|
|
452
|
+
* @param {boolean} autoescape - Per-bundle autoescape
|
|
453
|
+
* @param {function} nunjucksFilters - The NunjucksFilters factory, registered once
|
|
454
|
+
* @param {function} throwError - `self.throwError`, carried into the filter set
|
|
455
|
+
* @returns {*} A cached or newly built shared nunjucks Environment
|
|
456
|
+
*/
|
|
457
|
+
function getNunjucksAsyncEnv(nunjucks, templateRoot, ginaLoader, autoescape, nunjucksFilters, throwError) {
|
|
458
|
+
if (!process.gina._nunjucksAsyncEnvs) {
|
|
459
|
+
process.gina._nunjucksAsyncEnvs = Object.create(null);
|
|
460
|
+
}
|
|
461
|
+
// Drop all cached async envs when the nunjucks module was hot-swapped
|
|
462
|
+
// (dev-mode project refresh) — envs are bound to the module that built them.
|
|
463
|
+
if (process.gina._nunjucksAsyncEnvsOwner !== nunjucks) {
|
|
464
|
+
process.gina._nunjucksAsyncEnvs = Object.create(null);
|
|
465
|
+
process.gina._nunjucksAsyncEnvsOwner = nunjucks;
|
|
466
|
+
}
|
|
467
|
+
var key = templateRoot;
|
|
468
|
+
if (!process.gina._nunjucksAsyncEnvs[key]) {
|
|
469
|
+
var adapter = buildLoaderAdapter(nunjucks, ginaLoader);
|
|
470
|
+
var env = new nunjucks.Environment(adapter, {
|
|
471
|
+
autoescape: (autoescape !== false),
|
|
472
|
+
throwOnUndefined: false,
|
|
473
|
+
trimBlocks: false,
|
|
474
|
+
lstripBlocks: false
|
|
475
|
+
});
|
|
476
|
+
// #B25 / #TPL1 Tier-2 — register the gina filters ONCE on the shared env
|
|
477
|
+
// (context-free; per-request context flows via _renderALS).
|
|
478
|
+
registerGinaFilters(env, nunjucksFilters, throwError);
|
|
479
|
+
process.gina._nunjucksAsyncEnvs[key] = env;
|
|
480
|
+
}
|
|
481
|
+
return process.gina._nunjucksAsyncEnvs[key];
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Async-loader nunjucks render delegate. Signature matches the other delegates
|
|
486
|
+
* so controller.js can dispatch to it interchangeably.
|
|
487
|
+
*
|
|
488
|
+
* @param {object} userData - Controller-supplied template data
|
|
489
|
+
* @param {boolean=} displayInspector - Dev Inspector toggle (deferred — unused in the MVP)
|
|
490
|
+
* @param {object=} errOptions - Options when invoked from the error pipeline
|
|
491
|
+
* @param {object} deps - Injected controller refs ({ self, local, getData, hasViews, setResources, headersSent, ... })
|
|
492
|
+
* @returns {Promise<void>}
|
|
493
|
+
*
|
|
494
|
+
* @example
|
|
495
|
+
* // Selected automatically by controller.js when the bundle configures
|
|
496
|
+
* // render.engine = 'nunjucks' AND settings.template.nunjucks.loader; the
|
|
497
|
+
* // controller action just calls self.render(data).
|
|
498
|
+
*/
|
|
499
|
+
module.exports = async function renderNunjucksAsync(userData, displayInspector, errOptions, deps) {
|
|
500
|
+
var self = deps.self;
|
|
501
|
+
var local = deps.local;
|
|
502
|
+
var getData = deps.getData;
|
|
503
|
+
var hasViews = deps.hasViews;
|
|
504
|
+
var headersSent = deps.headersSent;
|
|
505
|
+
var setResources = deps.setResources; // #TPL1 — populates data.page.view.stylesheets/.scripts for asset injection
|
|
506
|
+
|
|
507
|
+
// Function-scoped captures of the per-request refs (#M1 race fix — mirror of
|
|
508
|
+
// render-nunjucks/render-swig-async). This render awaits (the promisified
|
|
509
|
+
// env.render); capturing isolates post-await reads from a concurrent
|
|
510
|
+
// throwError null-out on the controller closure.
|
|
511
|
+
var req = local.req;
|
|
512
|
+
var res = local.res;
|
|
513
|
+
var _next = local.next;
|
|
514
|
+
|
|
515
|
+
// #HDR5/#HDR16 — per-request CSP nonce (set on req by gina.plugins.Csp({useNonce:true})).
|
|
516
|
+
var _cspNonce = (req && req._ginaCspNonce) ? req._ginaCspNonce : null;
|
|
517
|
+
|
|
518
|
+
// Fetch the resolved nunjucks module (project-installed; bundle startup
|
|
519
|
+
// already validated it via nunjucksResolver.load). get() throws if no load
|
|
520
|
+
// succeeded — surface cleanly via throwError.
|
|
521
|
+
var nunjucks;
|
|
522
|
+
try {
|
|
523
|
+
nunjucks = (libRef && libRef.nunjucksResolver)
|
|
524
|
+
? libRef.nunjucksResolver.get()
|
|
525
|
+
: require('../../lib/nunjucks-resolver').get();
|
|
526
|
+
} catch (err) {
|
|
527
|
+
return self.throwError(err);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// No-view short-circuit (e.g. redirect responses reach render() without a
|
|
531
|
+
// configured template).
|
|
532
|
+
if (!hasViews || !hasViews()) {
|
|
533
|
+
sendHtmlResponse(local, '', req, res);
|
|
534
|
+
local.req = null;
|
|
535
|
+
local.res = null;
|
|
536
|
+
local.next = null;
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// If the pipeline already sent headers (an upstream throwError beat us), stop.
|
|
541
|
+
if (headersSent && headersSent()) { return; }
|
|
542
|
+
|
|
543
|
+
var localOptions = errOptions || local.options;
|
|
544
|
+
|
|
545
|
+
var data;
|
|
546
|
+
try {
|
|
547
|
+
data = getData();
|
|
548
|
+
} catch (dataErr) {
|
|
549
|
+
return self.throwError(dataErr);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// Error-interception — render(err) with a non-2xx status + an error object
|
|
553
|
+
// routes to the framework error page rather than rendering. Mirrors
|
|
554
|
+
// render-nunjucks.js / render-swig-async.js.
|
|
555
|
+
if (
|
|
556
|
+
!localOptions.isRenderingCustomError
|
|
557
|
+
&& data && data.page && data.page.data
|
|
558
|
+
&& typeof(data.page.data.status) !== 'undefined'
|
|
559
|
+
&& !String(data.page.data.status).startsWith('2')
|
|
560
|
+
&& typeof(data.page.data.error) !== 'undefined'
|
|
561
|
+
) {
|
|
562
|
+
var errorObject = {
|
|
563
|
+
status: data.page.data.status,
|
|
564
|
+
error: data.page.data.error || data.page.data.message,
|
|
565
|
+
message: data.page.data.message || data.page.data.error,
|
|
566
|
+
stack: data.page.data.stack
|
|
567
|
+
};
|
|
568
|
+
try {
|
|
569
|
+
console.error('[render-nunjucks-async] ' + data.page.data.status + ' from upstream — routing to throwError');
|
|
570
|
+
} catch (e) { /* ignore */ }
|
|
571
|
+
return self.throwError(errorObject);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// Registry key — the SAME expression initNunjucksEngine used to stash the
|
|
575
|
+
// loader (conf.content.templates._common.html), so the two sides never diverge.
|
|
576
|
+
var loaderKey = localOptions.conf
|
|
577
|
+
&& localOptions.conf.content
|
|
578
|
+
&& localOptions.conf.content.templates
|
|
579
|
+
&& localOptions.conf.content.templates._common
|
|
580
|
+
&& localOptions.conf.content.templates._common.html;
|
|
581
|
+
|
|
582
|
+
var stash = (loaderKey && process.gina._nunjucksLoaders) ? process.gina._nunjucksLoaders[loaderKey] : null;
|
|
583
|
+
if (!stash || !stash.loader) {
|
|
584
|
+
return self.throwError(new Error(
|
|
585
|
+
'[render-nunjucks-async] no async nunjucks loader registered for bundle ' + localOptions.bundle +
|
|
586
|
+
' — initNunjucksEngine did not build one (was settings.template.nunjucks.loader removed at runtime?)'
|
|
587
|
+
));
|
|
588
|
+
}
|
|
589
|
+
var ginaLoader = stash.loader;
|
|
590
|
+
|
|
591
|
+
// Merge user data into the render context — mirror render-nunjucks.js:
|
|
592
|
+
// (a) branching stash (userData without a `page` key -> data.page.data),
|
|
593
|
+
// (b) top-level merge with per-key `page` handling (preserves page.view etc.),
|
|
594
|
+
// (c) framework-data restore (re-overlay getData() so page.environment /
|
|
595
|
+
// page.view / page.data.session survive a partial page.* from the controller).
|
|
596
|
+
if (userData && typeof(userData) === 'object') {
|
|
597
|
+
if (!userData.page) {
|
|
598
|
+
if (!data.page.data) { data.page.data = {}; }
|
|
599
|
+
Object.keys(userData).forEach(function (k) {
|
|
600
|
+
data.page.data[k] = userData[k];
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
Object.keys(userData).forEach(function (k) {
|
|
604
|
+
if (k === 'page' && data.page && typeof userData.page === 'object') {
|
|
605
|
+
Object.keys(userData.page).forEach(function (pk) {
|
|
606
|
+
data.page[pk] = userData.page[pk];
|
|
607
|
+
});
|
|
608
|
+
} else {
|
|
609
|
+
data[k] = userData[k];
|
|
610
|
+
}
|
|
611
|
+
});
|
|
612
|
+
data = merge(data, getData());
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// Bug-J — alias `data.data` to `data.page.data` so page-shell
|
|
616
|
+
// `{% set X = data.Y %}` resolves under nunjucks layout inheritance (swig
|
|
617
|
+
// does this via `_layouts/layout.html` `{% set data = page.data %}`). Without
|
|
618
|
+
// it a page-shell's `{% set document = data.document %}` evaluates to
|
|
619
|
+
// undefined. Parity with the sync render-nunjucks.js delegate.
|
|
620
|
+
if (data && data.page && data.page.data) {
|
|
621
|
+
data.data = data.page.data;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
// #HDR5/#HDR16 — expose the per-request CSP nonce to templates: top-level
|
|
625
|
+
// {{ cspNonce }} (render-nunjucks parity) AND {{ page.cspNonce }}
|
|
626
|
+
// (render-swig-async parity). Keys stay absent when no nonce is set.
|
|
627
|
+
if (_cspNonce) {
|
|
628
|
+
data.cspNonce = _cspNonce;
|
|
629
|
+
if (!data.page) { data.page = {}; }
|
|
630
|
+
data.page.cspNonce = _cspNonce;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// #B25 / #TPL1 Tier-2 — fetch the NunjucksFilters factory (registry with a
|
|
634
|
+
// require fallback so dev-mode refreshCore() lib-cache eviction can't return
|
|
635
|
+
// undefined). The gina filters are context-free now: they read per-request
|
|
636
|
+
// context from process.gina._renderALS at call time, registered once on a
|
|
637
|
+
// shared env (cache on) or per request on a fresh env (cache off).
|
|
638
|
+
var nunjucksFilters = (libRef && libRef.nunjucksFilters)
|
|
639
|
+
|| require('../../lib/nunjucks-filters');
|
|
640
|
+
|
|
641
|
+
// Tier-2 compiled-template reuse: opt-in via settings.template.nunjucks.loader.cache,
|
|
642
|
+
// force-disabled in dev so template edits are picked up live. When ON, a shared
|
|
643
|
+
// per-bundle Environment (loader.cache populates across requests) is reused;
|
|
644
|
+
// when OFF, a fresh Environment is built per request. EITHER WAY the render is
|
|
645
|
+
// wrapped in _renderALS.run() below, which closes the #B25 singleton race (the
|
|
646
|
+
// per-request env alone does NOT — the gina filters read a process-global
|
|
647
|
+
// singleton, so an async render can be stomped by a concurrent request between
|
|
648
|
+
// addFilter and the filter invocation).
|
|
649
|
+
var _useCache = (stash.cache === true) && (process.env.NODE_ENV_IS_DEV !== 'true');
|
|
650
|
+
|
|
651
|
+
var env;
|
|
652
|
+
try {
|
|
653
|
+
if (_useCache) {
|
|
654
|
+
env = getNunjucksAsyncEnv(nunjucks, loaderKey, ginaLoader, stash.autoescape, nunjucksFilters, self.throwError);
|
|
655
|
+
} else {
|
|
656
|
+
var adapter = buildLoaderAdapter(nunjucks, ginaLoader);
|
|
657
|
+
env = new nunjucks.Environment(adapter, {
|
|
658
|
+
autoescape: (stash.autoescape !== false),
|
|
659
|
+
throwOnUndefined: false,
|
|
660
|
+
trimBlocks: false,
|
|
661
|
+
lstripBlocks: false
|
|
662
|
+
});
|
|
663
|
+
registerGinaFilters(env, nunjucksFilters, self.throwError);
|
|
664
|
+
}
|
|
665
|
+
} catch (envErr) {
|
|
666
|
+
return self.throwError(envErr);
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// #TPL1 asset injection — populate data.page.view.stylesheets / .scripts so
|
|
670
|
+
// injectAssets() (post-render) can auto-inject the gina client bundle, CSS
|
|
671
|
+
// and JS into the off-disk render. Mirrors render-swig-async.js: isWithoutLayout
|
|
672
|
+
// (XHR/popin) responses filter the asset list to common-only via Collection.
|
|
673
|
+
if (typeof setResources === 'function') {
|
|
674
|
+
try {
|
|
675
|
+
var isWithoutLayout = !!localOptions.isWithoutLayout;
|
|
676
|
+
var localTemplateConf = localOptions.template;
|
|
677
|
+
if (isWithoutLayout && localTemplateConf) {
|
|
678
|
+
localTemplateConf = JSON.clone(localTemplateConf);
|
|
679
|
+
if (Collection && Array.isArray(localTemplateConf.javascripts)) {
|
|
680
|
+
localTemplateConf.javascripts = new Collection(localTemplateConf.javascripts)
|
|
681
|
+
.find({ isCommon: false }, { isCommon: true, name: 'gina' });
|
|
682
|
+
}
|
|
683
|
+
if (Collection && Array.isArray(localTemplateConf.stylesheets)) {
|
|
684
|
+
localTemplateConf.stylesheets = new Collection(localTemplateConf.stylesheets)
|
|
685
|
+
.find({ isCommon: false }, { isCommon: true, name: 'gina' });
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
setResources(localTemplateConf);
|
|
689
|
+
// Re-overlay getData() so the freshly-set page.view.stylesheets /
|
|
690
|
+
// .scripts reach `data` — the render-swig.js:609 "needed !!" step:
|
|
691
|
+
// setResources writes via the controller's set() into local.userData,
|
|
692
|
+
// getData() rebuilds the data object, and merge fills the new keys.
|
|
693
|
+
data = merge(data, getData());
|
|
694
|
+
} catch (resourcesErr) {
|
|
695
|
+
try { console.warn('[render-nunjucks-async] setResources failed: ' + (resourcesErr.message || resourcesErr)); } catch (e) {}
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
var templateName;
|
|
700
|
+
try {
|
|
701
|
+
templateName = resolveTemplatePath(data, localOptions);
|
|
702
|
+
} catch (pathErr) {
|
|
703
|
+
return self.throwError(pathErr);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
// Callback-form render is MANDATORY with an async loader — a sync
|
|
707
|
+
// env.render(name, ctx) returns null silently on an uncached template.
|
|
708
|
+
// nunjucks' async codegen drives resolve->getSource for the page template
|
|
709
|
+
// AND its transitive extends/include chain through the adapter.
|
|
710
|
+
//
|
|
711
|
+
// #B25 / #TPL1 Tier-2 — per-request render context for the context-free gina
|
|
712
|
+
// filters. Carried through process.gina._renderALS so the filters read THIS
|
|
713
|
+
// request's context at call time (not a concurrently-interleaved render's).
|
|
714
|
+
// The .run() wrap is UNCONDITIONAL — it closes the #B25 singleton race whether
|
|
715
|
+
// or not the compiled cache is opted in — and propagates the store across
|
|
716
|
+
// every await in the render (page template + transitive extends/include).
|
|
717
|
+
var _renderStore = {
|
|
718
|
+
options: JSON.clone(localOptions),
|
|
719
|
+
isProxyHost: computeIsProxyHost(req, localOptions),
|
|
720
|
+
throwError: self.throwError,
|
|
721
|
+
req: req,
|
|
722
|
+
res: res
|
|
723
|
+
};
|
|
724
|
+
|
|
725
|
+
var html;
|
|
726
|
+
try {
|
|
727
|
+
html = await getRenderALS().run(_renderStore, async function () {
|
|
728
|
+
return await new Promise(function (resolve, reject) {
|
|
729
|
+
env.render(templateName, data, function (err, out) {
|
|
730
|
+
if (err) { return reject(err); }
|
|
731
|
+
resolve(out);
|
|
732
|
+
});
|
|
733
|
+
});
|
|
734
|
+
});
|
|
735
|
+
} catch (renderErr) {
|
|
736
|
+
return self.throwError(renderErr);
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
// #TPL1 — post-render asset injection (stylesheets / scripts / ginaLoader /
|
|
740
|
+
// externalPlugins) onto the </head> / </body> anchors. Falls through with
|
|
741
|
+
// un-mutated HTML on any error so a mis-shaped template config never breaks
|
|
742
|
+
// the render.
|
|
743
|
+
try {
|
|
744
|
+
html = injectAssets(html, data, localOptions, _cspNonce);
|
|
745
|
+
} catch (assetErr) {
|
|
746
|
+
try { console.warn('[render-nunjucks-async] asset injection skipped: ' + (assetErr.message || assetErr)); } catch (e) {}
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
// The injected gina bootstrap (gina.onload.min.js) is a literal HTML string
|
|
750
|
+
// carrying {{ page.X }} / {{ page.environment.X }} / {{ page.data.session.X }}
|
|
751
|
+
// placeholders the engine never saw (inserted post-render); resolve them with
|
|
752
|
+
// whisper(). Mirrors render-nunjucks.js / render-swig-async.js. Without this,
|
|
753
|
+
// window.onGinaLoaded throws a JSON.parse SyntaxError and gina.popin /
|
|
754
|
+
// gina.session / gina.forms / onGenericXhrResponse stay undefined.
|
|
755
|
+
try {
|
|
756
|
+
if (data && data.page && typeof data.page === 'object' && typeof whisper === 'function') {
|
|
757
|
+
var ginaLoaderDic = {};
|
|
758
|
+
for (var _d in data.page) {
|
|
759
|
+
ginaLoaderDic['page.' + _d] = data.page[_d];
|
|
760
|
+
}
|
|
761
|
+
if (typeof data.page.environment === 'object' && data.page.environment !== null) {
|
|
762
|
+
for (var _k in data.page.environment) {
|
|
763
|
+
ginaLoaderDic['page.environment.' + _k] = data.page.environment[_k];
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
// gina.onload.min.js also references `{{ page.data.session.X }}` (depth 3).
|
|
767
|
+
if (data.page.data && typeof data.page.data === 'object' && data.page.data.session && typeof data.page.data.session === 'object') {
|
|
768
|
+
for (var _s in data.page.data.session) {
|
|
769
|
+
ginaLoaderDic['page.data.session.' + _s] = data.page.data.session[_s];
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
html = whisper(ginaLoaderDic, html, /\{{ ([a-zA-Z.]+) \}}/g);
|
|
773
|
+
}
|
|
774
|
+
} catch (whisperErr) {
|
|
775
|
+
try { console.warn('[render-nunjucks-async] ginaLoader whisper substitution skipped: ' + (whisperErr.message || whisperErr)); } catch (e) {}
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
// A concurrent throwError may have sent headers while we awaited — re-check.
|
|
779
|
+
if (headersSent && headersSent()) { return; }
|
|
780
|
+
|
|
781
|
+
sendHtmlResponse(local, html, req, res);
|
|
782
|
+
|
|
783
|
+
// Release per-request refs on the closure; the function-scoped captures stay
|
|
784
|
+
// alive until return.
|
|
785
|
+
local.req = null;
|
|
786
|
+
local.res = null;
|
|
787
|
+
local.next = null;
|
|
788
|
+
};
|