gina 0.6.12 → 0.6.13
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 +1 -1
- package/README.md +24 -17
- package/ROADMAP.md +3 -2
- package/framework/v0.6.13/VERSION +1 -0
- package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/js/gina.js +8 -0
- package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/js/gina.min.js +165 -165
- package/framework/v0.6.13/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
- package/framework/v0.6.13/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
- package/framework/{v0.6.12 → v0.6.13}/core/config.js +26 -0
- package/framework/v0.6.13/core/connectors/redis/index.js +62 -0
- package/framework/v0.6.13/core/connectors/redis/lib/kv-store.js +394 -0
- package/framework/v0.6.13/core/connectors/sqlite/lib/kv-store.js +316 -0
- package/framework/{v0.6.12 → v0.6.13}/core/controller/controller.js +202 -0
- package/framework/{v0.6.12 → v0.6.13}/core/gna.js +85 -0
- package/framework/{v0.6.12 → v0.6.13}/core/model/entity.js +13 -5
- package/framework/{v0.6.12 → v0.6.13}/core/router.js +147 -56
- package/framework/{v0.6.12 → v0.6.13}/core/server.js +61 -0
- package/framework/{v0.6.12 → v0.6.13}/lib/cmd/service/help.txt +8 -2
- package/framework/{v0.6.12 → v0.6.13}/lib/cmd/service/start.js +1 -1
- package/framework/{v0.6.12 → v0.6.13}/lib/index.js +18 -0
- package/framework/v0.6.13/lib/kv/package.json +7 -0
- package/framework/v0.6.13/lib/kv/src/main.js +862 -0
- package/framework/v0.6.13/lib/kv-store.js +112 -0
- package/framework/v0.6.13/lib/rate-limit/package.json +6 -0
- package/framework/v0.6.13/lib/rate-limit/src/main.js +399 -0
- package/framework/{v0.6.12 → v0.6.13}/lib/routing/src/main.js +8 -0
- package/framework/{v0.6.12 → v0.6.13}/package.json +1 -1
- package/gna.js +4 -4
- package/llms.txt +13 -3
- package/package.json +3 -3
- package/schema/routing.json +30 -0
- package/schema/settings.json +101 -0
- package/types/index.d.ts +9 -0
- package/framework/v0.6.12/VERSION +0 -1
- package/framework/v0.6.12/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
- package/framework/v0.6.12/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
- package/framework/v0.6.12/core/connectors/redis/index.js +0 -36
- /package/framework/{v0.6.12 → v0.6.13}/AUTHORS +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/LICENSE +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/html/nolayout.html +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/html/static.html +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/img/android-chrome-192x192.png +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/img/android-chrome-512x512.png +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/img/apple-touch-icon.png +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/img/favicon-16x16.png +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/img/favicon-32x32.png +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/img/favicon.ico +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.css +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/beemaster/index.html +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/css/gina.min.css +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.br +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.gz +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/html/statusbar.html +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.br +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.gz +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/inspector/have_heart_one-webfont.woff2 +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/inspector/index.html +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/inspector/inspector.css +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/inspector/inspector.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/inspector/logo.svg +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.br +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.gz +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/ai/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/ai/lib/connector.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/couchbase/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/couchbase/lib/connector.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/couchbase/lib/connector.v3.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/couchbase/lib/connector.v4.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/couchbase/lib/n1ql.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/couchbase/lib/session-store.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/couchbase/lib/session-store.v3.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/couchbase/lib/session-store.v4.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/couchbase/lib/storage-store.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/duckdb/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/duckdb/lib/connector.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/mongodb/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/mongodb/lib/connector.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/mongodb/lib/job-store.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/mongodb/lib/pipeline-loader.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/mongodb/lib/session-store.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/mysql/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/mysql/lib/connector.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/param-redact.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/postgresql/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/postgresql/lib/connector.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/redis/lib/connector.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/redis/lib/job-store.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/redis/lib/render-cache-store.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/redis/lib/session-store.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/scylladb/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/scylladb/lib/connector.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/scylladb/lib/session-store.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/sql-parser.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/sqlite/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/sqlite/lib/connector.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/sqlite/lib/job-store.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/connectors/sqlite/lib/session-store.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/content.encoding +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/controller/controller.framework.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/controller/controller.render-json.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/controller/controller.render-nunjucks-async.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/controller/controller.render-nunjucks.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/controller/controller.render-stream.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/controller/controller.render-swig-async.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/controller/controller.render-swig.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/controller/controller.render-v1.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/controller/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/controller/inspector-window-emit.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/controller/release-banner.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/dev/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/dev/lib/class.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/dev/lib/factory.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/dev/lib/tools.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/locales/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/locales/currency.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/locales/dist/language/en.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/locales/dist/language/fr.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/locales/dist/region/en.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/locales/dist/region/fr.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/locales/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/mime.types +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/model/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/model/template/entityFactory.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/model/template/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/csrf/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/csrf/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/csrf/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/coep/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/coep/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/coep/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/coop/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/coop/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/coop/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/corp/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/corp/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/corp/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/csp/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/csp/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/csp/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/hide-powered-by/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/hide-powered-by/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/hide-powered-by/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/hsts/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/hsts/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/hsts/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/origin-agent-cluster/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/origin-agent-cluster/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/origin-agent-cluster/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/referrer-policy/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/referrer-policy/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/referrer-policy/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-content-type-options/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-content-type-options/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-content-type-options/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-dns-prefetch-control/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-dns-prefetch-control/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-dns-prefetch-control/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-download-options/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-download-options/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-download-options/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-frame-options/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-frame-options/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-frame-options/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-xss-protection/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-xss-protection/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/security-headers/x-xss-protection/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/session/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/session/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/session/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/storage/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/storage/build.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/storage/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/storage/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/validator/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/validator/build.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/validator/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/validator/src/form-validator.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/plugins/lib/validator/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/server.express.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/server.isaac.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/status.codes +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/_gitignore +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle/config/app.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle/config/connectors.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle/config/routing.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle/config/settings.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle/config/settings.server.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle/config/templates.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle/config/watchers.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle/controllers/controller.content.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle/controllers/controller.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle/controllers/setup.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle/locales/en.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle_namespace/controllers/controller.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle_public/css/default.css +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle_public/css/home.css +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle_public/css/vendor/readme.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle_public/favicon.ico +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle_public/js/components/x-checklist.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle_public/js/vendor/readme.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle_public/manifest.webmanifest +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle_public/readme.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle_public/sw.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle_templates/handlers/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle_templates/html/content/homepage.html +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle_templates/html/includes/error-msg-noscript.html +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle_templates/html/includes/error-msg-outdated-browser.html +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle_templates/html/includes/x-checklist.html +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/boilerplate/bundle_templates/html/layouts/main.html +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/command/gina.bat.tpl +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/command/gina.tpl +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/conf/env.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/conf/manifest.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/conf/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/conf/settings.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/conf/statics.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/conf/templates.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/error/client/json/401.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/error/client/json/403.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/error/client/json/404.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/error/server/html/50x.html +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/error/server/json/500.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/error/server/json/503.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/core/template/extensions/logger/config.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/console.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/context.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/data/LICENSE +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/data/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/data/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/data/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/dateFormat.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/json/LICENSE +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/json/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/json/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/json/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/path.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/plugins/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/plugins/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/plugins/src/api-error.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/plugins/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/prototypes.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/task.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/helpers/text.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/admin/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/admin/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/archiver/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/archiver/build.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/archiver/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/archiver/src/dep/jszip.min.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/archiver/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/async/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/async/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/audit/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/audit/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/audit-store.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/authn/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/authn/src/lockout.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/authn/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/authn/src/totp.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/authz-gate/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/authz-gate/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cache/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cache/build.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cache/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cache/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/aliases.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/audit/arguments.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/audit/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/audit/verify.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/add.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/arguments.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/build.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/copy.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/cp.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/help.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/inc/name-rewrite.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/list.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/man.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/mcp-start.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/mcp.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/oas.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/openapi.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/remove.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/rename.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/restart.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/rm.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/start.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/status.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/stop.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/bundle/types.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/cache/arguments.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/cache/clear.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/cache/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/cache/stats.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/connector/add.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/connector/arguments.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/connector/help.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/connector/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/connector/infer.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/connector/list.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/connector/migrate.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/connector/models.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/connector/remove.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/connector/rm.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/connector/test.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/container/arguments.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/container/help.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/container/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/container/man.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/container/ps.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/container/stop.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/controller/add.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/controller/arguments.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/controller/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/controller/inc/args.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/controller/inc/namespace.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/controller/inc/reference-rewrite.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/controller/inc/reference-scan.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/controller/inc/scaffold.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/controller/remove.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/controller/rename.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/controller/rm.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/env/add.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/env/get.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/env/help.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/env/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/env/link-dev.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/env/list.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/env/remove.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/env/rm.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/env/set.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/env/unset.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/env/use.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/add.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/arguments.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/build.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/dot.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/get.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/help.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/init.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/link-node-modules.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/link.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/list.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/man.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/msg.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/open.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/remove.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/reset.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/restart.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/set.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/start.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/status.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/stop.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/tail.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/update.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/framework/version.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/gina-dev.1.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/gina-framework.1.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/gina.1.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/helper.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/i18n/add.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/i18n/arguments.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/i18n/export.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/i18n/help.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/i18n/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/i18n/import.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/i18n/scan.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/image/_host.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/image/arguments.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/image/build.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/image/help.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/image/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/image/list.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/image/man.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/image/rm.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/image/run.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/inspector/help.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/inspector/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/inspector/open.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/man-render.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/minion/arguments.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/minion/help.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/minion/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/minion/kill.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/minion/list.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/msg.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/port/help.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/port/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/port/inc/scan.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/port/list.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/port/reset.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/port/set.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/add.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/arguments.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/backup.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/build.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/help.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/import.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/list.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/man.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/move.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/remove.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/rename.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/restart.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/restore.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/rm.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/start.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/status.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/project/stop.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/protocol/arguments.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/protocol/help.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/protocol/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/protocol/list.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/protocol/remove.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/protocol/set.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/scope/add.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/scope/help.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/scope/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/scope/link-local.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/scope/link-production.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/scope/list.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/scope/remove.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/scope/rm.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/scope/use.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/secrets/arguments.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/secrets/check.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/secrets/help.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/secrets/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/secrets/scan.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/service/help.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/service/list.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/service/man.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/storage/arguments.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/storage/gc.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/storage/help.txt +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/storage/stats.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/storage/verify.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd/view/add.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd-status-format/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cmd-status-format/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/collection/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/collection/build.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/collection/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/collection/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/config.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/connector-config/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/connector-config/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/connector-error/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/connector-error/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/connector-registry/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/connector-registry/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cron/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cron/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/cron/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/domain/LICENSE +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/domain/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/domain/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/domain/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/dto/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/dto/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/dto-pipe/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/dto-pipe/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/dto-types/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/dto-types/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/generator/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/i18n/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/i18n/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/image-build/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/image-build/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/inherits/LICENSE +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/inherits/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/inherits/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/inherits/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/inspector-events/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/inspector-events/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/inspector-redact/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/inspector-redact/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/instrument/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/instrument/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/job/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/job/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/job-store.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/json-config-header/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/json-config-header/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/loading-state/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/loading-state/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/logger/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/logger/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/logger/src/containers/default/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/logger/src/containers/file/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/logger/src/containers/file/lib/logrotator/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/logger/src/containers/file/lib/logrotator/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/logger/src/containers/mq/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/logger/src/containers/mq/listener.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/logger/src/containers/mq/speaker.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/logger/src/helper.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/logger/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/maintenance/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/maintenance/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/math/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/mcp-dispatch/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/mcp-dispatch/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/mcp-http/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/mcp-http/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/mcp-server/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/mcp-server/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/merge/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/merge/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/merge/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/metrics/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/metrics/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/model.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/net-locality/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/net-locality/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/nunjucks-filters/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/nunjucks-filters/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/nunjucks-filters/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/nunjucks-resolver/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/nunjucks-resolver/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/proc.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/push/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/push/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/release-watch/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/release-watch/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/render-cache/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/render-cache/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/render-cache-store.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/routing/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/routing/build.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/routing/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/routing/src/radix.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/routing-introspect/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/routing-introspect/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/secrets/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/secrets/src/backends/env.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/secrets/src/backends/file.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/secrets/src/env-file.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/secrets/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/session-store.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/shell.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/sqlite-driver.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/state.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/storage/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/storage/src/local-cas.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/storage/src/local-stream.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/storage/src/local.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/storage/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/storage/src/meta-store.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/storage/src/s3.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/storage/src/util.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/storage-store.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/swig-filters/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/swig-filters/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/swig-filters/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/swig-resolver/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/swig-resolver/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/template-loaders/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/template-loaders/src/loaders/http.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/template-loaders/src/loaders/memory.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/template-loaders/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/url/README.md +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/url/index.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/url/routing.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/uuid/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/uuid/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/validator.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/watcher/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/watcher/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/ws-framing/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/ws-framing/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/ws-query/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/ws-query/src/main.js +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/ws-session/package.json +0 -0
- /package/framework/{v0.6.12 → v0.6.13}/lib/ws-session/src/main.js +0 -0
|
@@ -0,0 +1,862 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the gina package.
|
|
3
|
+
* Copyright (c) 2009-2026 Rhinostone <contact@gina.io>
|
|
4
|
+
*
|
|
5
|
+
* For the full copyright and license information, please view the LICENSE
|
|
6
|
+
* file that was distributed with this source code.
|
|
7
|
+
*/
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @module lib/kv
|
|
12
|
+
* @description General-purpose key-value primitive (#KV1) — strict-declared
|
|
13
|
+
* NAMESPACES, each owning a backend and a failure policy, behind one
|
|
14
|
+
* promise-native handle reached from application code as `gina.kv('<name>')`
|
|
15
|
+
* (or `gina.kv()` for the `kv.default` namespace).
|
|
16
|
+
*
|
|
17
|
+
* **Strict by design.** A namespace must be declared under
|
|
18
|
+
* `settings.json > kv.namespaces` before `get()` hands it out — an unknown
|
|
19
|
+
* name THROWS at the call site rather than silently minting an empty store,
|
|
20
|
+
* for the same reason `lib/storage` keeps its drivers behind a throw-on-unknown
|
|
21
|
+
* contract: the throw is what surfaces a typo. A memory namespace is one line
|
|
22
|
+
* of config: `{ "kv": { "namespaces": { "counters": {} } } }`.
|
|
23
|
+
*
|
|
24
|
+
* **Value model.** Values are JSON-serialized strings end to end. `undefined`
|
|
25
|
+
* and `null` are REFUSED on every write (a stored `null` would be
|
|
26
|
+
* indistinguishable from a miss — store a wrapper object, or use `del()`).
|
|
27
|
+
* TTLs are MILLISECONDS and must be positive safe integers; `ttl: 0` is
|
|
28
|
+
* refused rather than read as "no expiry" (non-positive TTLs are the
|
|
29
|
+
* ambiguity class the render-cache boot lint refuses for the same reason).
|
|
30
|
+
*
|
|
31
|
+
* **The 13-op surface** (all promise-returning): `get` / `set` / `del` /
|
|
32
|
+
* `has` / `ttl` / `expire` / `setnx` (set-if-absent) / `consume` (atomic
|
|
33
|
+
* read-AND-delete — the one-shot-token op; the second reader gets `null`) /
|
|
34
|
+
* `incr` / `decr` (integer counters; `ttl` applies on CREATE only) /
|
|
35
|
+
* `delIfEquals` (compare-and-delete — the safe lock-release primitive) /
|
|
36
|
+
* `clear` (whole-namespace delete) / `getOrSet` (fetch-or-compute with
|
|
37
|
+
* per-process single-flight).
|
|
38
|
+
*
|
|
39
|
+
* **Deliberately NOT here** (demand-gated, documented boundary): redis data
|
|
40
|
+
* structures (lists, hashes, sets, streams, pub/sub — an app doing non-KV
|
|
41
|
+
* redis mints its own client), batch `mget`/`mset`, key scanning (use
|
|
42
|
+
* `clear()` or track your own keys), binary values (the storage layer owns
|
|
43
|
+
* bytes), and a first-class distributed-lock API (compose `setnx` +
|
|
44
|
+
* `delIfEquals`; locks done right need fencing and renewal policy that no
|
|
45
|
+
* half-primitive should imply).
|
|
46
|
+
*
|
|
47
|
+
* **Failure policy is per-namespace, not global** — the measured reason a
|
|
48
|
+
* single shared client was never the design: `failMode: 'closed'` (default)
|
|
49
|
+
* rejects the call on a backend error; `failMode: 'open'` degrades every op
|
|
50
|
+
* to its miss-shaped result with a warning, for cache-like namespaces where
|
|
51
|
+
* availability beats consistency. The knob is consulted on BACKEND errors
|
|
52
|
+
* only (validation errors always reject); the in-memory backend never
|
|
53
|
+
* errors, so it becomes operative with connector-backed stores.
|
|
54
|
+
*
|
|
55
|
+
* **Framework independence — the same hard structural rule as `lib/storage`.**
|
|
56
|
+
* This module must not require gina core, the `lib` registry, or the injected
|
|
57
|
+
* globals (`_()`, `getContext()`, `getConfig()`). Everything it needs is
|
|
58
|
+
* INJECTED by `gna.js` at boot: the validated `kv` block, any connector-backed
|
|
59
|
+
* stores (built through `lib/kv-store`), and a `warn` sink.
|
|
60
|
+
* `test/lib/kv-import-boundary.test.js` enforces it.
|
|
61
|
+
*
|
|
62
|
+
* **Scope.** Namespaces are PROCESS-GLOBAL, read once at boot from the
|
|
63
|
+
* STARTING bundle's `settings.json` (the `lib/storage` driver-set precedent);
|
|
64
|
+
* the whole feature is dormant — zero cost, `get()` throws a named error —
|
|
65
|
+
* when the `kv` block is absent.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* // settings.json
|
|
69
|
+
* // { "kv": {
|
|
70
|
+
* // "default" : "cache",
|
|
71
|
+
* // "namespaces" : {
|
|
72
|
+
* // "cache" : { "failMode": "open" },
|
|
73
|
+
* // "tokens" : {}
|
|
74
|
+
* // }
|
|
75
|
+
* // } }
|
|
76
|
+
*
|
|
77
|
+
* // controller code
|
|
78
|
+
* var tokens = gina.kv('tokens');
|
|
79
|
+
* tokens.setnx('t:' + hash, { uid: uid }, { ttl: 15 * 60 * 1000 })
|
|
80
|
+
* .then(function (won) {
|
|
81
|
+
* if (!won) { return self.throwError(409, 'already pending'); }
|
|
82
|
+
* });
|
|
83
|
+
* // redeem exactly once — a concurrent second redeemer resolves null:
|
|
84
|
+
* tokens.consume('t:' + hash).then(function (record) { ... });
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Module state — a singleton by design (plain-require'd from lib/index.js so
|
|
89
|
+
// namespace registries and sweep timers survive dev-mode refreshCore()).
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
|
|
92
|
+
/** @private */
|
|
93
|
+
var _namespaces = null;
|
|
94
|
+
/** @private */
|
|
95
|
+
var _default = null;
|
|
96
|
+
/** @private */
|
|
97
|
+
var _warn = function (msg) {
|
|
98
|
+
try { console.warn('[kv] ' + msg); } catch (warnErr) { /* no sink — drop */ }
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Namespace-name charset — mirrors the storage driver-name pattern.
|
|
103
|
+
* @constant
|
|
104
|
+
* @private
|
|
105
|
+
*/
|
|
106
|
+
var NAME_RE = /^[A-Za-z][A-Za-z0-9._-]*$/;
|
|
107
|
+
|
|
108
|
+
/** @constant @private */
|
|
109
|
+
var FAIL_MODES = ['closed', 'open'];
|
|
110
|
+
/** @constant @private */
|
|
111
|
+
var BLOCK_KEYS = ['default', 'namespaces'];
|
|
112
|
+
/** @constant @private */
|
|
113
|
+
var NS_KEYS = ['store', 'failMode', 'sweepInterval'];
|
|
114
|
+
/** @constant @private */
|
|
115
|
+
var MAX_KEY_LENGTH = 512;
|
|
116
|
+
/** @constant @private */
|
|
117
|
+
var DEFAULT_SWEEP_MS = 30000;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @typedef {object} KvNamespaceConf
|
|
121
|
+
* @property {string} [store] - `connectors.json` entry name backing this
|
|
122
|
+
* namespace. Omitted = the in-memory backend.
|
|
123
|
+
* @property {string} [failMode] - `'closed'` (default) or `'open'` — see the
|
|
124
|
+
* module description.
|
|
125
|
+
* @property {number} [sweepInterval] - Expired-entry sweep cadence in ms for the
|
|
126
|
+
* in-memory backend (default 30000).
|
|
127
|
+
*/
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The per-namespace BACKEND contract a connector `kv-store.js` must implement
|
|
131
|
+
* (`lib/kv-store` resolves and builds one per store-backed namespace at boot).
|
|
132
|
+
* Every method returns a Promise; every value crossing it is an opaque STRING
|
|
133
|
+
* (the facade owns JSON serialization). Key-prefixing per namespace is the
|
|
134
|
+
* implementation's duty — two namespaces may share one connectors entry.
|
|
135
|
+
*
|
|
136
|
+
* @typedef {object} KvStoreContract
|
|
137
|
+
* @property {function(string): Promise<?string>} get - `null` on miss.
|
|
138
|
+
* @property {function(string, string, ?number): Promise<void>} set - Third arg: TTL ms or `null`.
|
|
139
|
+
* @property {function(string): Promise<boolean>} del - `true` when a live entry existed.
|
|
140
|
+
* @property {function(string): Promise<boolean>} has
|
|
141
|
+
* @property {function(string): Promise<?number>} pttl - `null` miss, `-1` no expiry, else remaining ms.
|
|
142
|
+
* @property {function(string, number): Promise<boolean>} pexpire - `false` on miss.
|
|
143
|
+
* @property {function(string, string, ?number): Promise<boolean>} setnx - `true` when the write won.
|
|
144
|
+
* @property {function(string): Promise<?string>} consume - Atomic read-and-delete; `null` on miss.
|
|
145
|
+
* @property {function(string, number, ?number): Promise<number>} incrby - TTL applies on create only; rejects on a non-integer stored value.
|
|
146
|
+
* @property {function(string, string): Promise<boolean>} compareDel - Delete iff the stored string strictly equals the given one.
|
|
147
|
+
* @property {function(): Promise<number>} clear - Entries removed.
|
|
148
|
+
* @property {function(): void} close - Release timers/handles; no promise.
|
|
149
|
+
*/
|
|
150
|
+
|
|
151
|
+
// ---------------------------------------------------------------------------
|
|
152
|
+
// Configuration
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Validate a `settings.json > kv` block WITHOUT building anything.
|
|
157
|
+
*
|
|
158
|
+
* Same contract as the storage validator: an ABSENT block is "feature off",
|
|
159
|
+
* not an error; a declared-but-empty block warns; a malformed one is fatal.
|
|
160
|
+
* `gna.js` treats `fatal` as boot-aborting.
|
|
161
|
+
*
|
|
162
|
+
* @memberof module:lib/kv
|
|
163
|
+
* @param {?object} kvBlock - The raw `kv` block (may be `undefined`/`null`).
|
|
164
|
+
* @returns {{fatal: ?string, warnings: string[], namespaceCount: number}}
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* var v = kv.validateConfig(settings.kv);
|
|
168
|
+
* if (v.fatal) { abortBoot(v.fatal); }
|
|
169
|
+
*/
|
|
170
|
+
function validateConfig(kvBlock) {
|
|
171
|
+
var out = { fatal: null, warnings: [], namespaceCount: 0 };
|
|
172
|
+
|
|
173
|
+
if ( typeof(kvBlock) == 'undefined' || kvBlock === null ) {
|
|
174
|
+
return out; // not configured — the feature is off, which is not an error
|
|
175
|
+
}
|
|
176
|
+
if ( typeof(kvBlock) != 'object' || Array.isArray(kvBlock) ) {
|
|
177
|
+
out.fatal = '`settings.json > kv` must be an object — got ' + JSON.stringify(kvBlock);
|
|
178
|
+
return out;
|
|
179
|
+
}
|
|
180
|
+
for (var bk in kvBlock) {
|
|
181
|
+
if ( BLOCK_KEYS.indexOf(bk) < 0 ) {
|
|
182
|
+
out.warnings.push('`kv.' + bk + '` is not a recognised option — ignored (recognised: ' + BLOCK_KEYS.join(', ') + ')');
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
var namespaces = kvBlock.namespaces;
|
|
187
|
+
if ( typeof(namespaces) == 'undefined' || namespaces === null ) {
|
|
188
|
+
out.warnings.push('`kv` is declared but has no `namespaces` — no namespace will be available');
|
|
189
|
+
return out;
|
|
190
|
+
}
|
|
191
|
+
if ( typeof(namespaces) != 'object' || Array.isArray(namespaces) ) {
|
|
192
|
+
out.fatal = '`settings.json > kv.namespaces` must be an object keyed by namespace name';
|
|
193
|
+
return out;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
var names = Object.keys(namespaces);
|
|
197
|
+
out.namespaceCount = names.length;
|
|
198
|
+
|
|
199
|
+
for (var i = 0; i < names.length; i++) {
|
|
200
|
+
var name = names[i];
|
|
201
|
+
if ( !NAME_RE.test(name) ) {
|
|
202
|
+
out.fatal = 'namespace name `' + name + '` is invalid — names must match ^[A-Za-z][A-Za-z0-9._-]*$';
|
|
203
|
+
return out;
|
|
204
|
+
}
|
|
205
|
+
var conf = namespaces[name];
|
|
206
|
+
if ( conf === null || typeof(conf) != 'object' || Array.isArray(conf) ) {
|
|
207
|
+
out.fatal = '`kv.namespaces.' + name + '` must be an object — use {} for a plain in-memory namespace';
|
|
208
|
+
return out;
|
|
209
|
+
}
|
|
210
|
+
for (var ck in conf) {
|
|
211
|
+
if ( NS_KEYS.indexOf(ck) < 0 ) {
|
|
212
|
+
// a silently-dropped key reads as configured behaviour that
|
|
213
|
+
// never happens — name it (the storage-block convention)
|
|
214
|
+
out.warnings.push('`kv.namespaces.' + name + '.' + ck + '` is not a recognised option — ignored (recognised: ' + NS_KEYS.join(', ') + ')');
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if ( typeof(conf.store) != 'undefined' && (typeof(conf.store) != 'string' || conf.store.length === 0) ) {
|
|
218
|
+
out.fatal = '`kv.namespaces.' + name + '.store` must be a non-empty connectors.json entry name';
|
|
219
|
+
return out;
|
|
220
|
+
}
|
|
221
|
+
if ( typeof(conf.failMode) != 'undefined' && FAIL_MODES.indexOf(conf.failMode) < 0 ) {
|
|
222
|
+
out.fatal = '`kv.namespaces.' + name + '.failMode` must be one of: ' + FAIL_MODES.join(', ') + ' — got ' + JSON.stringify(conf.failMode);
|
|
223
|
+
return out;
|
|
224
|
+
}
|
|
225
|
+
if ( typeof(conf.sweepInterval) != 'undefined' && (!Number.isSafeInteger(conf.sweepInterval) || conf.sweepInterval <= 0) ) {
|
|
226
|
+
out.fatal = '`kv.namespaces.' + name + '.sweepInterval` must be a positive integer of milliseconds';
|
|
227
|
+
return out;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if ( typeof(kvBlock.default) != 'undefined' ) {
|
|
232
|
+
if ( typeof(kvBlock.default) != 'string' || kvBlock.default.length === 0 ) {
|
|
233
|
+
out.fatal = '`kv.default` must be a non-empty namespace name';
|
|
234
|
+
return out;
|
|
235
|
+
}
|
|
236
|
+
if ( names.indexOf(kvBlock.default) < 0 ) {
|
|
237
|
+
out.fatal = '`kv.default` names `' + kvBlock.default + '`, which is not a declared namespace (declared: ' + (names.join(', ') || 'none') + ')';
|
|
238
|
+
return out;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return out;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Build every declared namespace and install the module state. Once-only —
|
|
247
|
+
* a second call warns and is ignored (the `lib/job` store-adoption precedent).
|
|
248
|
+
*
|
|
249
|
+
* Call `validateConfig` first: `start` assumes a validated block and performs
|
|
250
|
+
* no re-validation of its own.
|
|
251
|
+
*
|
|
252
|
+
* @memberof module:lib/kv
|
|
253
|
+
* @param {object} kvBlock - The validated `kv` block.
|
|
254
|
+
* @param {object} [deps] - Injected dependencies (framework-independence seam).
|
|
255
|
+
* @param {object} [deps.stores] - Connector-backed stores keyed by namespace
|
|
256
|
+
* name (built by the caller through `lib/kv-store`);
|
|
257
|
+
* a namespace absent from this map gets the
|
|
258
|
+
* in-memory backend.
|
|
259
|
+
* @param {function} [deps.warn] - Warning sink (`gna.js` routes it to the logger).
|
|
260
|
+
* @returns {boolean} `true` when the namespaces were installed by THIS call.
|
|
261
|
+
*/
|
|
262
|
+
function start(kvBlock, deps) {
|
|
263
|
+
if ( _namespaces ) {
|
|
264
|
+
_warn('start: namespaces are already installed — the call was ignored. kv config changes need a bundle restart.');
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
deps = deps || {};
|
|
268
|
+
if ( typeof(deps.warn) == 'function' ) {
|
|
269
|
+
_warn = deps.warn;
|
|
270
|
+
}
|
|
271
|
+
var stores = deps.stores || {};
|
|
272
|
+
var namespaces = (kvBlock && kvBlock.namespaces) || {};
|
|
273
|
+
|
|
274
|
+
_namespaces = {};
|
|
275
|
+
for (var name in namespaces) {
|
|
276
|
+
var conf = namespaces[name] || {};
|
|
277
|
+
var store = Object.prototype.hasOwnProperty.call(stores, name)
|
|
278
|
+
? stores[name]
|
|
279
|
+
: createMemoryStore(conf);
|
|
280
|
+
_namespaces[name] = createNamespace(name, store, conf, _warn);
|
|
281
|
+
}
|
|
282
|
+
_default = (kvBlock && typeof(kvBlock.default) == 'string') ? kvBlock.default : null;
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Get a configured namespace handle.
|
|
288
|
+
*
|
|
289
|
+
* Throw-on-unknown is the contract, deliberately — it is what surfaces a
|
|
290
|
+
* typo'd namespace name at the call site instead of handing back a silently
|
|
291
|
+
* empty store (the `lib/storage` `get()` stance).
|
|
292
|
+
*
|
|
293
|
+
* @memberof module:lib/kv
|
|
294
|
+
* @param {string} [name] - Namespace name; omitted returns the `kv.default` namespace.
|
|
295
|
+
* @returns {object} The namespace handle (the 13-op surface).
|
|
296
|
+
* @throws {Error} When kv is not configured, when no default is declared and
|
|
297
|
+
* `name` was omitted, or when `name` is not a declared namespace.
|
|
298
|
+
*
|
|
299
|
+
* @example
|
|
300
|
+
* var cache = kv.get(); // the default namespace
|
|
301
|
+
* var tokens = kv.get('tokens'); // a named namespace
|
|
302
|
+
*/
|
|
303
|
+
function get(name) {
|
|
304
|
+
if ( !_namespaces ) {
|
|
305
|
+
throw new Error('[kv] not configured — add a `kv` block with `namespaces` to settings.json');
|
|
306
|
+
}
|
|
307
|
+
if ( typeof(name) == 'undefined' || name === null ) {
|
|
308
|
+
if ( !_default ) {
|
|
309
|
+
throw new Error('[kv] no `kv.default` is declared — call gina.kv(\'<name>\') with one of: ' + Object.keys(_namespaces).join(', '));
|
|
310
|
+
}
|
|
311
|
+
name = _default;
|
|
312
|
+
}
|
|
313
|
+
if ( !Object.prototype.hasOwnProperty.call(_namespaces, name) ) {
|
|
314
|
+
throw new Error('[kv] no namespace `' + name + '` (configured: ' + (Object.keys(_namespaces).join(', ') || 'none') + ')');
|
|
315
|
+
}
|
|
316
|
+
return _namespaces[name];
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Names of the installed namespaces — the enumeration door for operator
|
|
321
|
+
* surfaces. Answers `[]` before {@link start} (or when kv is unconfigured),
|
|
322
|
+
* so an iterating caller needs no `isStarted()` pre-check. Names only: the
|
|
323
|
+
* handles stay behind {@link get}.
|
|
324
|
+
*
|
|
325
|
+
* @memberof module:lib/kv
|
|
326
|
+
* @returns {string[]} Namespace names, in configuration order.
|
|
327
|
+
*/
|
|
328
|
+
function list() {
|
|
329
|
+
return _namespaces ? Object.keys(_namespaces) : [];
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Whether {@link start} has installed namespaces.
|
|
334
|
+
*
|
|
335
|
+
* @memberof module:lib/kv
|
|
336
|
+
* @returns {boolean} `true` once namespaces are built.
|
|
337
|
+
*/
|
|
338
|
+
function isStarted() {
|
|
339
|
+
return !!_namespaces;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Release every namespace's backend (sweep timers, store handles) and clear
|
|
344
|
+
* module state. Test/teardown seam — the runtime never calls it (the
|
|
345
|
+
* `lib/storage` `reset()` precedent).
|
|
346
|
+
*
|
|
347
|
+
* @memberof module:lib/kv
|
|
348
|
+
* @returns {void}
|
|
349
|
+
*/
|
|
350
|
+
function reset() {
|
|
351
|
+
if ( _namespaces ) {
|
|
352
|
+
var names = Object.keys(_namespaces);
|
|
353
|
+
for (var i = 0; i < names.length; i++) {
|
|
354
|
+
try { _namespaces[names[i]]._close(); } catch (closeErr) { /* already closed */ }
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
_namespaces = null;
|
|
358
|
+
_default = null;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// ---------------------------------------------------------------------------
|
|
362
|
+
// Facade-level validation helpers
|
|
363
|
+
// ---------------------------------------------------------------------------
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Validate a caller-supplied key.
|
|
367
|
+
*
|
|
368
|
+
* @inner
|
|
369
|
+
* @param {*} key - Candidate key.
|
|
370
|
+
* @returns {?TypeError} The rejection to use, or `null` when the key is valid.
|
|
371
|
+
*/
|
|
372
|
+
function checkKey(key) {
|
|
373
|
+
if ( typeof(key) != 'string' || key.length === 0 ) {
|
|
374
|
+
return new TypeError('[kv] keys must be non-empty strings — got ' + (typeof key === 'string' ? 'an empty string' : typeof key));
|
|
375
|
+
}
|
|
376
|
+
if ( key.length > MAX_KEY_LENGTH ) {
|
|
377
|
+
return new TypeError('[kv] key exceeds the ' + MAX_KEY_LENGTH + '-character limit (got ' + key.length + ')');
|
|
378
|
+
}
|
|
379
|
+
return null;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Extract and validate a TTL from a per-call options object.
|
|
384
|
+
*
|
|
385
|
+
* @inner
|
|
386
|
+
* @param {*} opts - Caller options (`{ ttl }` accepted; absent = no expiry).
|
|
387
|
+
* @returns {{err: ?TypeError, ttl: ?number}} `ttl` in ms, or `null` for no expiry.
|
|
388
|
+
*/
|
|
389
|
+
function checkTtl(opts) {
|
|
390
|
+
if ( typeof(opts) == 'undefined' || opts === null ) {
|
|
391
|
+
return { err: null, ttl: null };
|
|
392
|
+
}
|
|
393
|
+
if ( typeof(opts) != 'object' || Array.isArray(opts) ) {
|
|
394
|
+
return { err: new TypeError('[kv] per-call options must be an object — got ' + JSON.stringify(opts)), ttl: null };
|
|
395
|
+
}
|
|
396
|
+
if ( typeof(opts.ttl) == 'undefined' || opts.ttl === null ) {
|
|
397
|
+
return { err: null, ttl: null };
|
|
398
|
+
}
|
|
399
|
+
if ( !Number.isSafeInteger(opts.ttl) || opts.ttl <= 0 ) {
|
|
400
|
+
// ttl: 0 is refused, never read as "no expiry" — non-positive TTLs are
|
|
401
|
+
// an ambiguity, not a request
|
|
402
|
+
return { err: new TypeError('[kv] `ttl` must be a positive integer of milliseconds — got ' + JSON.stringify(opts.ttl)), ttl: null };
|
|
403
|
+
}
|
|
404
|
+
return { err: null, ttl: opts.ttl };
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Serialize a caller value to its stored string form.
|
|
409
|
+
*
|
|
410
|
+
* @inner
|
|
411
|
+
* @param {*} value - Caller value.
|
|
412
|
+
* @returns {{err: ?TypeError, s: ?string}}
|
|
413
|
+
*/
|
|
414
|
+
function serializeValue(value) {
|
|
415
|
+
if ( typeof(value) == 'undefined' ) {
|
|
416
|
+
return { err: new TypeError('[kv] `undefined` cannot be stored — a dropped value is the silent-match-all class this refusal closes'), s: null };
|
|
417
|
+
}
|
|
418
|
+
if ( value === null ) {
|
|
419
|
+
return { err: new TypeError('[kv] `null` cannot be stored — it would be indistinguishable from a miss; store a wrapper object, or use del()'), s: null };
|
|
420
|
+
}
|
|
421
|
+
var s;
|
|
422
|
+
try {
|
|
423
|
+
s = JSON.stringify(value);
|
|
424
|
+
} catch (jsonErr) {
|
|
425
|
+
return { err: new TypeError('[kv] value is not JSON-serializable: ' + (jsonErr.message || jsonErr)), s: null };
|
|
426
|
+
}
|
|
427
|
+
if ( typeof(s) == 'undefined' ) {
|
|
428
|
+
return { err: new TypeError('[kv] value is not JSON-serializable (functions and symbols have no JSON form)'), s: null };
|
|
429
|
+
}
|
|
430
|
+
return { err: null, s: s };
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// ---------------------------------------------------------------------------
|
|
434
|
+
// In-memory backend
|
|
435
|
+
// ---------------------------------------------------------------------------
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Build the in-memory backend for one namespace: a Map of
|
|
439
|
+
* `key -> { v, exp }` with lazy expiry on read plus an unref'd interval
|
|
440
|
+
* sweep, implementing {@link KvStoreContract}.
|
|
441
|
+
*
|
|
442
|
+
* @memberof module:lib/kv
|
|
443
|
+
* @param {KvNamespaceConf} [conf] - Namespace configuration (`sweepInterval` honoured).
|
|
444
|
+
* @returns {KvStoreContract} The backend instance.
|
|
445
|
+
*/
|
|
446
|
+
function createMemoryStore(conf) {
|
|
447
|
+
var map = new Map();
|
|
448
|
+
var sweepMs = (conf && Number.isSafeInteger(conf.sweepInterval) && conf.sweepInterval > 0)
|
|
449
|
+
? conf.sweepInterval
|
|
450
|
+
: DEFAULT_SWEEP_MS;
|
|
451
|
+
|
|
452
|
+
var timer = setInterval(function sweepExpired() {
|
|
453
|
+
var now = Date.now();
|
|
454
|
+
map.forEach(function (rec, key) {
|
|
455
|
+
if ( rec.exp !== null && rec.exp <= now ) {
|
|
456
|
+
map.delete(key);
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
}, sweepMs);
|
|
460
|
+
// never keep the process alive for a sweep
|
|
461
|
+
if ( timer.unref ) { timer.unref(); }
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Return the live record for `key`, dropping it lazily when expired.
|
|
465
|
+
* @inner
|
|
466
|
+
* @param {string} key - Store key.
|
|
467
|
+
* @returns {?{v: string, exp: ?number}} The record, or `null`.
|
|
468
|
+
*/
|
|
469
|
+
var live = function (key) {
|
|
470
|
+
var rec = map.get(key);
|
|
471
|
+
if ( !rec ) { return null; }
|
|
472
|
+
if ( rec.exp !== null && rec.exp <= Date.now() ) {
|
|
473
|
+
map.delete(key);
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
476
|
+
return rec;
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
return {
|
|
480
|
+
get: function (key) {
|
|
481
|
+
var rec = live(key);
|
|
482
|
+
return Promise.resolve(rec ? rec.v : null);
|
|
483
|
+
},
|
|
484
|
+
set: function (key, s, ttlMs) {
|
|
485
|
+
map.set(key, { v: s, exp: ttlMs ? Date.now() + ttlMs : null });
|
|
486
|
+
return Promise.resolve();
|
|
487
|
+
},
|
|
488
|
+
del: function (key) {
|
|
489
|
+
var existed = !!live(key);
|
|
490
|
+
map.delete(key);
|
|
491
|
+
return Promise.resolve(existed);
|
|
492
|
+
},
|
|
493
|
+
has: function (key) {
|
|
494
|
+
return Promise.resolve(!!live(key));
|
|
495
|
+
},
|
|
496
|
+
pttl: function (key) {
|
|
497
|
+
var rec = live(key);
|
|
498
|
+
if ( !rec ) { return Promise.resolve(null); }
|
|
499
|
+
if ( rec.exp === null ) { return Promise.resolve(-1); }
|
|
500
|
+
return Promise.resolve(Math.max(0, rec.exp - Date.now()));
|
|
501
|
+
},
|
|
502
|
+
pexpire: function (key, ttlMs) {
|
|
503
|
+
var rec = live(key);
|
|
504
|
+
if ( !rec ) { return Promise.resolve(false); }
|
|
505
|
+
rec.exp = Date.now() + ttlMs;
|
|
506
|
+
return Promise.resolve(true);
|
|
507
|
+
},
|
|
508
|
+
setnx: function (key, s, ttlMs) {
|
|
509
|
+
if ( live(key) ) { return Promise.resolve(false); }
|
|
510
|
+
map.set(key, { v: s, exp: ttlMs ? Date.now() + ttlMs : null });
|
|
511
|
+
return Promise.resolve(true);
|
|
512
|
+
},
|
|
513
|
+
consume: function (key) {
|
|
514
|
+
var rec = live(key);
|
|
515
|
+
if ( !rec ) { return Promise.resolve(null); }
|
|
516
|
+
map.delete(key);
|
|
517
|
+
return Promise.resolve(rec.v);
|
|
518
|
+
},
|
|
519
|
+
incrby: function (key, by, ttlMs) {
|
|
520
|
+
var rec = live(key);
|
|
521
|
+
var cur = 0;
|
|
522
|
+
if ( rec ) {
|
|
523
|
+
cur = Number(rec.v);
|
|
524
|
+
if ( !Number.isSafeInteger(cur) ) {
|
|
525
|
+
return Promise.reject(new Error('[kv] value at key `' + key + '` is not an integer — incr/decr need an integer value'));
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
var next = cur + by;
|
|
529
|
+
if ( !Number.isSafeInteger(next) ) {
|
|
530
|
+
return Promise.reject(new Error('[kv] increment leaves the safe-integer range at key `' + key + '`'));
|
|
531
|
+
}
|
|
532
|
+
if ( rec ) {
|
|
533
|
+
rec.v = String(next); // ttl applies on CREATE only — keep the existing expiry
|
|
534
|
+
} else {
|
|
535
|
+
map.set(key, { v: String(next), exp: ttlMs ? Date.now() + ttlMs : null });
|
|
536
|
+
}
|
|
537
|
+
return Promise.resolve(next);
|
|
538
|
+
},
|
|
539
|
+
compareDel: function (key, s) {
|
|
540
|
+
var rec = live(key);
|
|
541
|
+
if ( rec && rec.v === s ) {
|
|
542
|
+
map.delete(key);
|
|
543
|
+
return Promise.resolve(true);
|
|
544
|
+
}
|
|
545
|
+
return Promise.resolve(false);
|
|
546
|
+
},
|
|
547
|
+
clear: function () {
|
|
548
|
+
var n = map.size; // includes any expired entries not yet swept
|
|
549
|
+
map.clear();
|
|
550
|
+
return Promise.resolve(n);
|
|
551
|
+
},
|
|
552
|
+
close: function () {
|
|
553
|
+
clearInterval(timer);
|
|
554
|
+
map.clear();
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// ---------------------------------------------------------------------------
|
|
560
|
+
// Namespace handle
|
|
561
|
+
// ---------------------------------------------------------------------------
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Build the public handle for one namespace over a {@link KvStoreContract}
|
|
565
|
+
* backend: JSON (de)serialization, key/TTL/value validation, the
|
|
566
|
+
* per-namespace failure policy, and getOrSet single-flight.
|
|
567
|
+
*
|
|
568
|
+
* @memberof module:lib/kv
|
|
569
|
+
* @param {string} name - Namespace name (already validated).
|
|
570
|
+
* @param {KvStoreContract} store - The backend.
|
|
571
|
+
* @param {KvNamespaceConf} [conf] - Namespace configuration (`failMode` honoured).
|
|
572
|
+
* @param {function} [warn] - Warning sink for failMode-open degrades.
|
|
573
|
+
* @returns {object} The 13-op namespace handle.
|
|
574
|
+
*/
|
|
575
|
+
function createNamespace(name, store, conf, warn) {
|
|
576
|
+
var failOpen = !!(conf && conf.failMode === 'open');
|
|
577
|
+
var sink = (typeof warn == 'function') ? warn : _warn;
|
|
578
|
+
var inflight = {};
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Backend-error policy: reject (`closed`) or degrade to the op's
|
|
582
|
+
* miss-shaped result with a warning (`open`). Validation errors never
|
|
583
|
+
* reach this — they reject before the backend is called.
|
|
584
|
+
*
|
|
585
|
+
* @inner
|
|
586
|
+
* @param {string} op - Operation label for the warning.
|
|
587
|
+
* @param {*} miss - The op's miss-shaped result.
|
|
588
|
+
* @returns {function(Error): *} A rejection handler.
|
|
589
|
+
*/
|
|
590
|
+
var degrade = function (op, miss) {
|
|
591
|
+
return function (err) {
|
|
592
|
+
if ( failOpen ) {
|
|
593
|
+
sink('namespace `' + name + '` ' + op + ' degraded (failMode=open): ' + (err && err.message || err));
|
|
594
|
+
return miss;
|
|
595
|
+
}
|
|
596
|
+
throw err;
|
|
597
|
+
};
|
|
598
|
+
};
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Parse a stored string back to its value. A corrupt entry is a backend
|
|
602
|
+
* DATA error — degradable under failMode open.
|
|
603
|
+
*
|
|
604
|
+
* @inner
|
|
605
|
+
* @param {string} s - Stored string.
|
|
606
|
+
* @param {string} key - Key, for the error message.
|
|
607
|
+
* @returns {*} The parsed value.
|
|
608
|
+
*/
|
|
609
|
+
var parseStored = function (s, key) {
|
|
610
|
+
try {
|
|
611
|
+
return JSON.parse(s);
|
|
612
|
+
} catch (parseErr) {
|
|
613
|
+
throw new Error('[kv] namespace `' + name + '` key `' + key + '`: stored value is not valid JSON (' + (parseErr.message || parseErr) + ')');
|
|
614
|
+
}
|
|
615
|
+
};
|
|
616
|
+
|
|
617
|
+
var self = {
|
|
618
|
+
/** @type {string} Namespace name (informational). */
|
|
619
|
+
name: name,
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* Read a key.
|
|
623
|
+
* @param {string} key
|
|
624
|
+
* @returns {Promise<*>} The value, or `null` on miss.
|
|
625
|
+
*/
|
|
626
|
+
get: function (key) {
|
|
627
|
+
var keyErr = checkKey(key);
|
|
628
|
+
if ( keyErr ) { return Promise.reject(keyErr); }
|
|
629
|
+
return store.get(key).then(function (s) {
|
|
630
|
+
return (s === null) ? null : parseStored(s, key);
|
|
631
|
+
}).catch(degrade('get', null));
|
|
632
|
+
},
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Write a key.
|
|
636
|
+
* @param {string} key
|
|
637
|
+
* @param {*} value - Any JSON-serializable value except `null`/`undefined`.
|
|
638
|
+
* @param {object} [opts] - `{ ttl }` in ms (positive integer).
|
|
639
|
+
* @returns {Promise<boolean>} `true` on success (`false` only under failMode open).
|
|
640
|
+
*/
|
|
641
|
+
set: function (key, value, opts) {
|
|
642
|
+
var keyErr = checkKey(key);
|
|
643
|
+
if ( keyErr ) { return Promise.reject(keyErr); }
|
|
644
|
+
var ttl = checkTtl(opts);
|
|
645
|
+
if ( ttl.err ) { return Promise.reject(ttl.err); }
|
|
646
|
+
var ser = serializeValue(value);
|
|
647
|
+
if ( ser.err ) { return Promise.reject(ser.err); }
|
|
648
|
+
return store.set(key, ser.s, ttl.ttl).then(function () {
|
|
649
|
+
return true;
|
|
650
|
+
}).catch(degrade('set', false));
|
|
651
|
+
},
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Delete a key.
|
|
655
|
+
* @param {string} key
|
|
656
|
+
* @returns {Promise<boolean>} `true` when a live entry existed.
|
|
657
|
+
*/
|
|
658
|
+
del: function (key) {
|
|
659
|
+
var keyErr = checkKey(key);
|
|
660
|
+
if ( keyErr ) { return Promise.reject(keyErr); }
|
|
661
|
+
return store.del(key).catch(degrade('del', false));
|
|
662
|
+
},
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* Whether a live entry exists.
|
|
666
|
+
* @param {string} key
|
|
667
|
+
* @returns {Promise<boolean>}
|
|
668
|
+
*/
|
|
669
|
+
has: function (key) {
|
|
670
|
+
var keyErr = checkKey(key);
|
|
671
|
+
if ( keyErr ) { return Promise.reject(keyErr); }
|
|
672
|
+
return store.has(key).catch(degrade('has', false));
|
|
673
|
+
},
|
|
674
|
+
|
|
675
|
+
/**
|
|
676
|
+
* Remaining lifetime of a key.
|
|
677
|
+
* @param {string} key
|
|
678
|
+
* @returns {Promise<?number>} `null` on miss, `-1` for no expiry, else remaining ms.
|
|
679
|
+
*/
|
|
680
|
+
ttl: function (key) {
|
|
681
|
+
var keyErr = checkKey(key);
|
|
682
|
+
if ( keyErr ) { return Promise.reject(keyErr); }
|
|
683
|
+
return store.pttl(key).catch(degrade('ttl', null));
|
|
684
|
+
},
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Set/replace the TTL of an existing key (the sliding-expiration op).
|
|
688
|
+
* @param {string} key
|
|
689
|
+
* @param {number} ttlMs - Positive integer ms.
|
|
690
|
+
* @returns {Promise<boolean>} `false` on miss.
|
|
691
|
+
*/
|
|
692
|
+
expire: function (key, ttlMs) {
|
|
693
|
+
var keyErr = checkKey(key);
|
|
694
|
+
if ( keyErr ) { return Promise.reject(keyErr); }
|
|
695
|
+
var ttl = checkTtl({ ttl: ttlMs });
|
|
696
|
+
if ( ttl.err ) { return Promise.reject(ttl.err); }
|
|
697
|
+
return store.pexpire(key, ttl.ttl).catch(degrade('expire', false));
|
|
698
|
+
},
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* Set-if-absent (conditional set).
|
|
702
|
+
* @param {string} key
|
|
703
|
+
* @param {*} value
|
|
704
|
+
* @param {object} [opts] - `{ ttl }` in ms.
|
|
705
|
+
* @returns {Promise<boolean>} `true` when the write won.
|
|
706
|
+
*/
|
|
707
|
+
setnx: function (key, value, opts) {
|
|
708
|
+
var keyErr = checkKey(key);
|
|
709
|
+
if ( keyErr ) { return Promise.reject(keyErr); }
|
|
710
|
+
var ttl = checkTtl(opts);
|
|
711
|
+
if ( ttl.err ) { return Promise.reject(ttl.err); }
|
|
712
|
+
var ser = serializeValue(value);
|
|
713
|
+
if ( ser.err ) { return Promise.reject(ser.err); }
|
|
714
|
+
return store.setnx(key, ser.s, ttl.ttl).catch(degrade('setnx', false));
|
|
715
|
+
},
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Atomic read-AND-delete — the one-shot-token op. Exactly one of any
|
|
719
|
+
* number of concurrent consumers resolves the value; the rest resolve
|
|
720
|
+
* `null`. This is NOT `get` + `del`: the atomicity is the contract.
|
|
721
|
+
* @param {string} key
|
|
722
|
+
* @returns {Promise<*>} The value, or `null`.
|
|
723
|
+
*/
|
|
724
|
+
consume: function (key) {
|
|
725
|
+
var keyErr = checkKey(key);
|
|
726
|
+
if ( keyErr ) { return Promise.reject(keyErr); }
|
|
727
|
+
return store.consume(key).then(function (s) {
|
|
728
|
+
return (s === null) ? null : parseStored(s, key);
|
|
729
|
+
}).catch(degrade('consume', null));
|
|
730
|
+
},
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* Atomically increment an integer counter.
|
|
734
|
+
* @param {string} key
|
|
735
|
+
* @param {number} [by=1] - Positive or negative safe integer.
|
|
736
|
+
* @param {object} [opts] - `{ ttl }` in ms — applies when the counter is CREATED only.
|
|
737
|
+
* @returns {Promise<?number>} The new value (`null` only under failMode open).
|
|
738
|
+
*/
|
|
739
|
+
incr: function (key, by, opts) {
|
|
740
|
+
var keyErr = checkKey(key);
|
|
741
|
+
if ( keyErr ) { return Promise.reject(keyErr); }
|
|
742
|
+
if ( typeof(by) == 'undefined' || by === null ) { by = 1; }
|
|
743
|
+
if ( !Number.isSafeInteger(by) ) {
|
|
744
|
+
return Promise.reject(new TypeError('[kv] `by` must be a safe integer — got ' + JSON.stringify(by)));
|
|
745
|
+
}
|
|
746
|
+
var ttl = checkTtl(opts);
|
|
747
|
+
if ( ttl.err ) { return Promise.reject(ttl.err); }
|
|
748
|
+
return store.incrby(key, by, ttl.ttl).catch(degrade('incr', null));
|
|
749
|
+
},
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
* Atomically decrement an integer counter — `incr` with the sign flipped.
|
|
753
|
+
* @param {string} key
|
|
754
|
+
* @param {number} [by=1]
|
|
755
|
+
* @param {object} [opts] - `{ ttl }` in ms — applies on create only.
|
|
756
|
+
* @returns {Promise<?number>} The new value (`null` only under failMode open).
|
|
757
|
+
*/
|
|
758
|
+
decr: function (key, by, opts) {
|
|
759
|
+
if ( typeof(by) == 'undefined' || by === null ) { by = 1; }
|
|
760
|
+
if ( !Number.isSafeInteger(by) ) {
|
|
761
|
+
return Promise.reject(new TypeError('[kv] `by` must be a safe integer — got ' + JSON.stringify(by)));
|
|
762
|
+
}
|
|
763
|
+
return self.incr(key, -by, opts);
|
|
764
|
+
},
|
|
765
|
+
|
|
766
|
+
/**
|
|
767
|
+
* Compare-and-delete: delete `key` iff its stored value equals
|
|
768
|
+
* `expected` — the safe lock/lease-release primitive (an unconditional
|
|
769
|
+
* `del` after a lease expiry can delete someone else's entry).
|
|
770
|
+
* Equality is on the JSON-serialized form this facade writes.
|
|
771
|
+
* @param {string} key
|
|
772
|
+
* @param {*} expected - Same value rules as `set`.
|
|
773
|
+
* @returns {Promise<boolean>} `true` when the entry matched and was deleted.
|
|
774
|
+
*/
|
|
775
|
+
delIfEquals: function (key, expected) {
|
|
776
|
+
var keyErr = checkKey(key);
|
|
777
|
+
if ( keyErr ) { return Promise.reject(keyErr); }
|
|
778
|
+
var ser = serializeValue(expected);
|
|
779
|
+
if ( ser.err ) { return Promise.reject(ser.err); }
|
|
780
|
+
return store.compareDel(key, ser.s).catch(degrade('delIfEquals', false));
|
|
781
|
+
},
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* Delete every entry in the namespace.
|
|
785
|
+
* @returns {Promise<number>} Entries removed (including expired ones not yet swept).
|
|
786
|
+
*/
|
|
787
|
+
clear: function () {
|
|
788
|
+
return store.clear().catch(degrade('clear', 0));
|
|
789
|
+
},
|
|
790
|
+
|
|
791
|
+
/**
|
|
792
|
+
* Fetch-or-compute: return the cached value, or run `loader`, store its
|
|
793
|
+
* result, and return it. Concurrent same-process callers whose misses
|
|
794
|
+
* overlap an in-flight load SHARE that load (single-flight); a read
|
|
795
|
+
* that missed before the load completed may still invoke the loader
|
|
796
|
+
* once more — the collapse is best-effort, not a lock. No negative
|
|
797
|
+
* caching: a throwing loader rejects every sharer and caches nothing.
|
|
798
|
+
* The invoking caller receives the loader's value AS-IS; later readers
|
|
799
|
+
* see its JSON round-trip.
|
|
800
|
+
* @param {string} key
|
|
801
|
+
* @param {object|function} [opts] - `{ ttl }` in ms; may be omitted entirely.
|
|
802
|
+
* @param {function} loader - `function (key) { return value | Promise<value> }`.
|
|
803
|
+
* @returns {Promise<*>}
|
|
804
|
+
*/
|
|
805
|
+
getOrSet: function (key, opts, loader) {
|
|
806
|
+
if ( typeof(opts) == 'function' && typeof(loader) == 'undefined' ) {
|
|
807
|
+
loader = opts;
|
|
808
|
+
opts = null;
|
|
809
|
+
}
|
|
810
|
+
var keyErr = checkKey(key);
|
|
811
|
+
if ( keyErr ) { return Promise.reject(keyErr); }
|
|
812
|
+
var ttl = checkTtl(opts);
|
|
813
|
+
if ( ttl.err ) { return Promise.reject(ttl.err); }
|
|
814
|
+
if ( typeof(loader) != 'function' ) {
|
|
815
|
+
return Promise.reject(new TypeError('[kv] getOrSet needs a loader function — got ' + typeof loader));
|
|
816
|
+
}
|
|
817
|
+
return self.get(key).then(function (hit) {
|
|
818
|
+
if ( hit !== null ) { return hit; }
|
|
819
|
+
if ( Object.prototype.hasOwnProperty.call(inflight, key) ) {
|
|
820
|
+
return inflight[key];
|
|
821
|
+
}
|
|
822
|
+
var flight = Promise.resolve().then(function () {
|
|
823
|
+
return loader(key);
|
|
824
|
+
}).then(function (loaded) {
|
|
825
|
+
if ( typeof(loaded) == 'undefined' ) {
|
|
826
|
+
throw new TypeError('[kv] getOrSet loader returned `undefined` for key `' + key + '` — return a value, or reject');
|
|
827
|
+
}
|
|
828
|
+
return self.set(key, loaded, ttl.ttl !== null ? { ttl: ttl.ttl } : null).then(function () {
|
|
829
|
+
return loaded;
|
|
830
|
+
});
|
|
831
|
+
});
|
|
832
|
+
var clearFlight = function () { delete inflight[key]; };
|
|
833
|
+
flight.then(clearFlight, clearFlight);
|
|
834
|
+
inflight[key] = flight;
|
|
835
|
+
return flight;
|
|
836
|
+
});
|
|
837
|
+
},
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* Release the backend (timers, handles). Called by `reset()`.
|
|
841
|
+
* @private
|
|
842
|
+
* @returns {void}
|
|
843
|
+
*/
|
|
844
|
+
_close: function () {
|
|
845
|
+
if ( store.close ) { store.close(); }
|
|
846
|
+
}
|
|
847
|
+
};
|
|
848
|
+
|
|
849
|
+
return self;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
module.exports = {
|
|
853
|
+
validateConfig : validateConfig,
|
|
854
|
+
start : start,
|
|
855
|
+
get : get,
|
|
856
|
+
list : list,
|
|
857
|
+
isStarted : isStarted,
|
|
858
|
+
reset : reset,
|
|
859
|
+
// test seams — may change without notice (the lib/storage underscore convention)
|
|
860
|
+
_createMemoryStore : createMemoryStore,
|
|
861
|
+
_createNamespace : createNamespace
|
|
862
|
+
};
|