diff --git a/.gitignore b/.gitignore index a60345b..e9a36c6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ node_modules/ # temp temp/ + +# cds +gen/ diff --git a/.npmrc b/.npmrc index 43c97e7..03866b7 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,2 @@ package-lock=false +yes=true diff --git a/cds-plugin.js b/cds-plugin.js index 24fc72e..5fd6742 100644 --- a/cds-plugin.js +++ b/cds-plugin.js @@ -5,20 +5,24 @@ const cds = require("@sap/cds"); const { initializeFeatures } = require("./src/singleton"); const activate = async () => { - if (cds.env.featureToggles?.config || cds.env.featureToggles?.configFile) { - cds.env.requires["FeatureService"] = { model: "@cap-js-community/feature-toggle-library" }; + const envFeatureToggles = cds.env.featureToggles; + if (envFeatureToggles?.config || envFeatureToggles?.configFile) { + // TODO this is currently done in package.json, because "cds build" ignores it otherwise. However, it should happen + // dynamically. + // cds.env.requires["FeatureService"] = { model: "@cap-js-community/feature-toggle-library" }; - if (Array.isArray(cds.env.featureToggles.serviceAccessRoles)) { + if (Array.isArray(envFeatureToggles.serviceAccessRoles)) { cds.on("loaded", (csn) => { if (csn.definitions.FeatureService) { - csn.definitions.FeatureService["@requires"] = cds.env.featureToggles.serviceAccessRoles; + csn.definitions.FeatureService["@requires"] = envFeatureToggles.serviceAccessRoles; } }); } + // TODO for the "cds build" use case, this initialize makes no sense await initializeFeatures({ - config: cds.env.featureToggles.config, - configFile: cds.env.featureToggles.configFile, + config: envFeatureToggles.config, + configFile: envFeatureToggles.configFile, }); } }; diff --git a/example-cap-server/.npmrc b/example-cap-server/.npmrc index 43c97e7..03866b7 100644 --- a/example-cap-server/.npmrc +++ b/example-cap-server/.npmrc @@ -1 +1,2 @@ package-lock=false +yes=true diff --git a/example-cap-server/http/feature-service.http b/example-cap-server/http/feature-service.http index b3e20fd..0f93937 100644 --- a/example-cap-server/http/feature-service.http +++ b/example-cap-server/http/feature-service.http @@ -2,59 +2,69 @@ GET {{base_url}}/rest/feature/state Authorization: Basic system system -### redis_update | check 1 +### redis_update | memory 1 POST {{base_url}}/rest/feature/redisUpdate Authorization: Basic system system Content-Type: application/json { - "key": "/check/priority", - "value": 1 + "key": "/memory/logInterval", + "value": 1000 } -### redis_update | check 2 +### redis_update | memory 2 POST {{base_url}}/rest/feature/redisUpdate Authorization: Basic system system Content-Type: application/json { - "key": "/check/priority", - "value": 10, - "scope": { "tenant": "people" } + "key": "/memory/logInterval", + "value": 100 } -### redis_update | check 3 +### redis_update | memory off POST {{base_url}}/rest/feature/redisUpdate Authorization: Basic system system Content-Type: application/json { - "key": "/check/priority", - "value": 100, - "scope": { "user": "alice@wonderland.com", "tenant": "people" } + "key": "/memory/logInterval", + "value": null } +### redis_update | check 1 +POST {{base_url}}/rest/feature/redisUpdate +Authorization: Basic system system +Content-Type: application/json + +{ + "key": "/check/priority", + "value": 1 +} -### redis_update | memory 1 +### redis_update | check 2 POST {{base_url}}/rest/feature/redisUpdate Authorization: Basic system system Content-Type: application/json { - "key": "/memory/logInterval", - "value": 1000 + "key": "/check/priority", + "value": 10, + "scope": { "tenant": "people" } } -### redis_update | memory 2 +### redis_update | check 3 POST {{base_url}}/rest/feature/redisUpdate Authorization: Basic system system Content-Type: application/json { - "key": "/memory/logInterval", - "value": 100 + "key": "/check/priority", + "value": 100, + "scope": { "user": "alice@wonderland.com" } } + ### redis_update | reset POST {{base_url}}/rest/feature/redisUpdate Authorization: Basic system system diff --git a/example-cap-server/package.json b/example-cap-server/package.json index 370389d..c09ffe9 100644 --- a/example-cap-server/package.json +++ b/example-cap-server/package.json @@ -6,17 +6,23 @@ "start": "npm run copy-library && npm run serve", "copy-library": "npx shx rm -rf node_modules/@cap-js-community/feature-toggle-library && npx shx mkdir -p node_modules/@cap-js-community/feature-toggle-library && npx shx cp -R ../package.json ../index.cds ../cds-plugin.js ../src node_modules/@cap-js-community/feature-toggle-library", "serve": "cds-serve", - "cloc": "npx cloc --vcs=git --read-lang-def=cloc.def .", + "build": "cds build --production", + "cloc": "npx cloc --vcs=git --exclude-ext=def --read-lang-def=cloc.def .", "upgrade": "npm up --save && npx shx rm -rf node_modules && npm i" }, "dependencies": { - "@cap-js-community/feature-toggle-library": "^0.6.9", + "@cap-js-community/feature-toggle-library": "*", "@sap/cds": "^7.2.0", + "@sap/cds-dk": "^7.2.0", "express": "^4.18.2" }, "cds": { "featureToggles": { - "configFile": "./srv/feature/features.yaml" + "configFile": "./srv/feature/features.yaml", + "serviceAccessRoles": [ + "system-user", + "custom-role" + ] } } } diff --git a/example-cap-server/srv/feature/features.yaml b/example-cap-server/srv/feature/features.yaml index 2029f2e..149a69a 100644 --- a/example-cap-server/srv/feature/features.yaml +++ b/example-cap-server/srv/feature/features.yaml @@ -14,4 +14,3 @@ fallbackValue: 0 validations: - regex: '^\d+$' - - { module: "./srv/feature/validators.js", call: validateTenantScope } diff --git a/example-cap-server/srv/feature/index.js b/example-cap-server/srv/feature/index.js index 5e99878..fe8c0c0 100644 --- a/example-cap-server/srv/feature/index.js +++ b/example-cap-server/srv/feature/index.js @@ -1,16 +1,7 @@ "use strict"; -const pathlib = require("path"); - -const FEATURES_FILEPATH = pathlib.join(__dirname, "features.yaml"); - -const FEATURE = Object.freeze({ +module.exports = Object.freeze({ CHECK_API_PRIORITY: "/check/priority", MEM_STAT_LOG_INTERVAL: "/memory/logInterval", }); - -module.exports = { - FEATURES_FILEPATH, - FEATURE, -}; diff --git a/example-cap-server/srv/memoryStatistics.js b/example-cap-server/srv/memoryStatistics.js index 687ad6a..d6e2a9b 100644 --- a/example-cap-server/srv/memoryStatistics.js +++ b/example-cap-server/srv/memoryStatistics.js @@ -7,9 +7,7 @@ const { singleton: { registerFeatureValueChangeHandler, getFeatureValue }, DynamicIntervalController, } = require("@cap-js-community/feature-toggle-library"); -const { - FEATURE: { MEM_STAT_LOG_INTERVAL }, -} = require("./feature"); +const { MEM_STAT_LOG_INTERVAL } = require("./feature"); const logger = cds.log("memoryStatistics"); diff --git a/example-cap-server/srv/service/check-service.js b/example-cap-server/srv/service/check-service.js index ab5b8bc..54293f0 100644 --- a/example-cap-server/srv/service/check-service.js +++ b/example-cap-server/srv/service/check-service.js @@ -4,7 +4,7 @@ const { singleton: { getFeatureValue }, } = require("@cap-js-community/feature-toggle-library"); -const { FEATURE } = require("../feature"); +const { CHECK_API_PRIORITY } = require("../feature"); const LOW_VALUE_RESPONSES = ["hello", "barely made it"]; @@ -15,7 +15,7 @@ const HIGH_VALUE_RESPONSES = ["well done", "full success", "huzzah", "celebratio const HIGH_BOUNDARY = 100; const priorityHandler = async (context) => { - const value = getFeatureValue(FEATURE.CHECK_API_PRIORITY, { user: context.user.id, tenant: context.tenant }); + const value = getFeatureValue(CHECK_API_PRIORITY, { user: context.user.id, tenant: context.tenant }); const messages = value >= HIGH_BOUNDARY ? HIGH_VALUE_RESPONSES diff --git a/package.json b/package.json index a4e28d6..18f60cf 100644 --- a/package.json +++ b/package.json @@ -53,5 +53,12 @@ "cloud-foundry" ], "author": "Richard Lindner ", - "license": "Apache-2.0" + "license": "Apache-2.0", + "cds": { + "requires": { + "FeatureService": { + "model": "@cap-js-community/feature-toggle-library" + } + } + } } diff --git a/src/service/feature-service.cds b/src/service/feature-service.cds index 8f923d4..56fbf01 100644 --- a/src/service/feature-service.cds +++ b/src/service/feature-service.cds @@ -1,5 +1,5 @@ @protocol: 'rest' -@impl: './feature-service.js' + @(requires: ['system-user']) service FeatureService { type JSON {};