From ec5b854ec526e5f38b5ab991bcb1c08aedcae8a5 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 8 Nov 2021 19:35:36 +0000 Subject: [PATCH 01/16] chore(deps): update typescript-eslint monorepo to v5.3.1 --- package.json | 4 +-- yarn.lock | 82 ++++++++++++++++++++++++++-------------------------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index bc2ce0790c..68921af0d2 100644 --- a/package.json +++ b/package.json @@ -131,8 +131,8 @@ "@types/stoppable": "1.1.1", "@types/supertest": "2.0.11", "@types/uuid": "8.3.1", - "@typescript-eslint/eslint-plugin": "5.3.0", - "@typescript-eslint/parser": "5.3.0", + "@typescript-eslint/eslint-plugin": "5.3.1", + "@typescript-eslint/parser": "5.3.1", "copyfiles": "2.4.1", "coveralls": "3.1.1", "del-cli": "4.0.1", diff --git a/yarn.lock b/yarn.lock index db866be85a..707279fdb8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -924,13 +924,13 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@5.3.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.3.0.tgz#a55ae72d28ffeb6badd817fe4566c9cced1f5e29" - integrity sha512-ARUEJHJrq85aaiCqez7SANeahDsJTD3AEua34EoQN9pHS6S5Bq9emcIaGGySt/4X2zSi+vF5hAH52sEen7IO7g== +"@typescript-eslint/eslint-plugin@5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.3.1.tgz#d8ff412f10f54f6364e7fd7c1e70eb6767f434c3" + integrity sha512-cFImaoIr5Ojj358xI/SDhjog57OK2NqlpxwdcgyxDA3bJlZcJq5CPzUXtpD7CxI2Hm6ATU7w5fQnnkVnmwpHqw== dependencies: - "@typescript-eslint/experimental-utils" "5.3.0" - "@typescript-eslint/scope-manager" "5.3.0" + "@typescript-eslint/experimental-utils" "5.3.1" + "@typescript-eslint/scope-manager" "5.3.1" debug "^4.3.2" functional-red-black-tree "^1.0.1" ignore "^5.1.8" @@ -938,60 +938,60 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@5.3.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.3.0.tgz#ee56b4957547ed2b0fc7451205e41502e664f546" - integrity sha512-NFVxYTjKj69qB0FM+piah1x3G/63WB8vCBMnlnEHUsiLzXSTWb9FmFn36FD9Zb4APKBLY3xRArOGSMQkuzTF1w== +"@typescript-eslint/experimental-utils@5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.3.1.tgz#bbd8f9b67b4d5fdcb9d2f90297d8fcda22561e05" + integrity sha512-RgFn5asjZ5daUhbK5Sp0peq0SSMytqcrkNfU4pnDma2D8P3ElZ6JbYjY8IMSFfZAJ0f3x3tnO3vXHweYg0g59w== dependencies: "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.3.0" - "@typescript-eslint/types" "5.3.0" - "@typescript-eslint/typescript-estree" "5.3.0" + "@typescript-eslint/scope-manager" "5.3.1" + "@typescript-eslint/types" "5.3.1" + "@typescript-eslint/typescript-estree" "5.3.1" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/parser@5.3.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.3.0.tgz#7879f15e26d370ed3f653fb7dd06479531ed3ab9" - integrity sha512-rKu/yAReip7ovx8UwOAszJVO5MgBquo8WjIQcp1gx4pYQCwYzag+I5nVNHO4MqyMkAo0gWt2gWUi+36gWAVKcw== +"@typescript-eslint/parser@5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.3.1.tgz#8ff1977c3d3200c217b3e4628d43ef92f89e5261" + integrity sha512-TD+ONlx5c+Qhk21x9gsJAMRohWAUMavSOmJgv3JGy9dgPhuBd5Wok0lmMClZDyJNLLZK1JRKiATzCKZNUmoyfw== dependencies: - "@typescript-eslint/scope-manager" "5.3.0" - "@typescript-eslint/types" "5.3.0" - "@typescript-eslint/typescript-estree" "5.3.0" + "@typescript-eslint/scope-manager" "5.3.1" + "@typescript-eslint/types" "5.3.1" + "@typescript-eslint/typescript-estree" "5.3.1" debug "^4.3.2" -"@typescript-eslint/scope-manager@5.3.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.3.0.tgz#97d0ccc7c9158e89e202d5e24ce6ba49052d432e" - integrity sha512-22Uic9oRlTsPppy5Tcwfj+QET5RWEnZ5414Prby465XxQrQFZ6nnm5KnXgnsAJefG4hEgMnaxTB3kNEyjdjj6A== +"@typescript-eslint/scope-manager@5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.3.1.tgz#3cfbfbcf5488fb2a9a6fbbe97963ee1e8d419269" + integrity sha512-XksFVBgAq0Y9H40BDbuPOTUIp7dn4u8oOuhcgGq7EoDP50eqcafkMVGrypyVGvDYHzjhdUCUwuwVUK4JhkMAMg== dependencies: - "@typescript-eslint/types" "5.3.0" - "@typescript-eslint/visitor-keys" "5.3.0" + "@typescript-eslint/types" "5.3.1" + "@typescript-eslint/visitor-keys" "5.3.1" -"@typescript-eslint/types@5.3.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.3.0.tgz#af29fd53867c2df0028c57c36a655bd7e9e05416" - integrity sha512-fce5pG41/w8O6ahQEhXmMV+xuh4+GayzqEogN24EK+vECA3I6pUwKuLi5QbXO721EMitpQne5VKXofPonYlAQg== +"@typescript-eslint/types@5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.3.1.tgz#afaa715b69ebfcfde3af8b0403bf27527912f9b7" + integrity sha512-bG7HeBLolxKHtdHG54Uac750eXuQQPpdJfCYuw4ZI3bZ7+GgKClMWM8jExBtp7NSP4m8PmLRM8+lhzkYnSmSxQ== -"@typescript-eslint/typescript-estree@5.3.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.3.0.tgz#4f68ddd46dc2983182402d2ab21fb44ad94988cf" - integrity sha512-FJ0nqcaUOpn/6Z4Jwbtf+o0valjBLkqc3MWkMvrhA2TvzFXtcclIM8F4MBEmYa2kgcI8EZeSAzwoSrIC8JYkug== +"@typescript-eslint/typescript-estree@5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.3.1.tgz#50cc4bfb93dc31bc75e08ae52e29fcb786d606ec" + integrity sha512-PwFbh/PKDVo/Wct6N3w+E4rLZxUDgsoII/GrWM2A62ETOzJd4M6s0Mu7w4CWsZraTbaC5UQI+dLeyOIFF1PquQ== dependencies: - "@typescript-eslint/types" "5.3.0" - "@typescript-eslint/visitor-keys" "5.3.0" + "@typescript-eslint/types" "5.3.1" + "@typescript-eslint/visitor-keys" "5.3.1" debug "^4.3.2" globby "^11.0.4" is-glob "^4.0.3" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@5.3.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.3.0.tgz#a6258790f3b7b2547f70ed8d4a1e0c3499994523" - integrity sha512-oVIAfIQuq0x2TFDNLVavUn548WL+7hdhxYn+9j3YdJJXB7mH9dAmZNJsPDa7Jc+B9WGqoiex7GUDbyMxV0a/aw== +"@typescript-eslint/visitor-keys@5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.3.1.tgz#c2860ff22939352db4f3806f34b21d8ad00588ba" + integrity sha512-3cHUzUuVTuNHx0Gjjt5pEHa87+lzyqOiHXy/Gz+SJOCW1mpw9xQHIIEwnKn+Thph1mgWyZ90nboOcSuZr/jTTQ== dependencies: - "@typescript-eslint/types" "5.3.0" + "@typescript-eslint/types" "5.3.1" eslint-visitor-keys "^3.0.0" abab@^2.0.3, abab@^2.0.5: From 106c9cebde751b36b5f1e26c0dabc863df096009 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Mon, 8 Nov 2021 22:58:02 +0100 Subject: [PATCH 02/16] docs: Clarify that the proxy does not expose disabled flags (#1094) * docs: fix typo 'preformat' -> 'performant' * docs: clarify that proxy returns _only_ enabled toggles This is based on feedback we got that said: > Right now biggest disappointment is that docs doesn't match an exact > JS proxy libraries and their usage. For example, we couldn't make > feature flag return enabled: false, instead it just hides/not return > the flag at all. --- website/docs/sdks/unleash-proxy.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/docs/sdks/unleash-proxy.md b/website/docs/sdks/unleash-proxy.md index 1a121bfc9f..504eeabfc0 100644 --- a/website/docs/sdks/unleash-proxy.md +++ b/website/docs/sdks/unleash-proxy.md @@ -5,14 +5,14 @@ title: Unleash Proxy > The unleash-proxy is compatible with all Unleash Enterprise versions and Unleash Open-Source v4. You should reach out to **support@getunleash.io** if you want the Unleash Team to host the Unleash Proxy for you. -A lot of our users wanted to use feature toggles in their single-page and native applications. To solve this in a preformat and privacy concerned way we built The Unleash Proxy +A lot of our users wanted to use feature toggles in their single-page and native applications. To solve this in a performant and privacy concerned way we built The Unleash Proxy The Unleash Proxy sits between the Unleash API and the application. It provides a simple and super-fast API, as it has all the data it needs available in memory. The proxy solves three important aspects: - **Performance** – The proxy will cache all toggles in memory, and will be running on the edge, close to your end-users. A single instance will be able to handle thousands of request/sec, and you can scale it easily by adding additional instances. -- **Security** – The proxy evaluates the feature flags for the user on the server-side, and only exposes the results of enabled feature flags for a specific user. +- **Security** – The proxy evaluates the feature flags for the user on the server-side, and exposes results for feature flags that are enabled for a specific user (flags not enabled for that specific user are _not_ exposed). - **Privacy** – If you run the proxy yourself (we can host it as well though) we will not see your end users. This means that you still have full control of your end-users, the way it should be! ![The Unleash Proxy](/img/The-unleash-proxy.png) @@ -111,7 +111,7 @@ The Unleash Proxy has a very simple API. It takes the [Unleash Context](../user_ ### We care about Privacy! {#we-care-about-privacy} -The Unleash Proxy is important because you should not expose your entire toggle configurations to your end users! Single page apps works in context of a specific user. The proxy will only return the evaluated toggles (with variants) that should be enabled for those specific users in that specific context. +The Unleash Proxy is important because you should not expose your entire set of toggle configurations to your end users. Single page apps work in the context of a specific user. The proxy allows you to only provide data that relates to that one user: _The proxy will only return the evaluated toggles (with variants) that should be enabled for that specific user in that specific context._ Most of our customers prefer to run The Unleash Proxy themselves. PS! We actually prefer this as we don’t want to see your users. Running it is pretty simple, it is either a small Node.js process you start or a docker image you use. (We can of course host the proxy for you also.) From 6b30670ccb77b52b5f3cf32f331d7b34b3efa42c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Nov 2021 22:58:28 +0100 Subject: [PATCH 03/16] chore(deps): update dependency eslint-config-airbnb-typescript to v15 (#1091) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 68921af0d2..eac48d0781 100644 --- a/package.json +++ b/package.json @@ -138,7 +138,7 @@ "del-cli": "4.0.1", "eslint": "8.2.0", "eslint-config-airbnb-base": "14.2.1", - "eslint-config-airbnb-typescript": "14.0.2", + "eslint-config-airbnb-typescript": "15.0.0", "eslint-config-prettier": "8.3.0", "eslint-plugin-import": "2.25.2", "eslint-plugin-prettier": "4.0.0", diff --git a/yarn.lock b/yarn.lock index 707279fdb8..ac71ebb4fd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2475,10 +2475,10 @@ eslint-config-airbnb-base@14.2.1, eslint-config-airbnb-base@^14.2.1: object.assign "^4.1.2" object.entries "^1.1.2" -eslint-config-airbnb-typescript@14.0.2: - version "14.0.2" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-14.0.2.tgz#4dc1583b9eab671bb011dea7d4ff1fc0d88e6e09" - integrity sha512-oaVR63DqpRUiOOeSVxIzhD3FXbqJRH+7Lt9GCMsS9SKgrRW3XpZINN2FO4JEsnaHEGkktumd0AHE9K7KQNuXSQ== +eslint-config-airbnb-typescript@15.0.0: + version "15.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-15.0.0.tgz#c88007b3cca5dd0f47125420ca5e8f6efac418fd" + integrity sha512-DTWGwqytbTnB8kSKtmkrGkRf3xwTs2l15shSH0w/3Img47AQwCCrIA/ON/Uj0XXBxP31LHyEItPXeuH3mqCNLA== dependencies: eslint-config-airbnb-base "^14.2.1" From 0b3c4fd6133d071c3da0514ffce766ac754175ff Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 9 Nov 2021 00:06:17 +0000 Subject: [PATCH 04/16] fix(deps): update dependency knex to v0.95.14 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index eac48d0781..6b923da9f2 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "helmet": "^4.1.0", "joi": "^17.3.0", "js-yaml": "^4.1.0", - "knex": "0.95.13", + "knex": "0.95.14", "log4js": "^6.0.0", "memoizee": "^0.4.15", "mime": "^2.4.2", diff --git a/yarn.lock b/yarn.lock index ac71ebb4fd..f2d513ed88 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4557,10 +4557,10 @@ kleur@^3.0.3: resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -knex@0.95.13: - version "0.95.13" - resolved "https://registry.yarnpkg.com/knex/-/knex-0.95.13.tgz#b0547c91f6a02662f08c5bf9efbb12d660f392f7" - integrity sha512-XagG/iYA4RabYy1BmgY607Q00kBduOgb/Nej3+UDcCNdmuzDvZcfFo/726BYhfxv5amTBtGjewodZrTNbO63VA== +knex@0.95.14: + version "0.95.14" + resolved "https://registry.yarnpkg.com/knex/-/knex-0.95.14.tgz#47eca7757cbc5872b7c9a3c67ae3b7ac6d00cf10" + integrity sha512-j4qLjWySrC/JRRVtOpoR2LcS1yBOsd7Krc6mEukPvmTDX/w11pD52Pq9FYR56/kLXGeAV8jFdWBjsZFi1mscWg== dependencies: colorette "2.0.16" commander "^7.1.0" From c4035353a09210b64c93adce4167a94e5c3ef729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20Conradi=20=C3=98sthus?= Date: Tue, 9 Nov 2021 14:21:07 +0100 Subject: [PATCH 05/16] docs: add syntax highlighting to react-sdk --- website/docs/sdks/proxy-react.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docs/sdks/proxy-react.md b/website/docs/sdks/proxy-react.md index 31557d635b..7954c13327 100644 --- a/website/docs/sdks/proxy-react.md +++ b/website/docs/sdks/proxy-react.md @@ -15,7 +15,7 @@ yarn add @unleash/proxy-client-react Import the provider like this in your entrypoint file (typically index.js/ts): -``` +```js import FlagProvider from '@unleash/proxy-client-react'; const config = { @@ -38,7 +38,7 @@ ReactDOM.render( To check if a feature is enabled: -``` +```js import { useFlag } from '@unleash/proxy-client-react'; const TestComponent = () => { @@ -55,7 +55,7 @@ export default TestComponent; To check variants: -``` +```js import { useVariant } from '@unleash/proxy-client-react'; const TestComponent = () => { @@ -76,7 +76,7 @@ export default TestComponent; Follow the following steps in order to update the unleash context: -``` +```js import { useUnleashContext, useFlag } from '@unleash/proxy-client-react' const MyComponent = ({ userId }) => { From d22b8503fd30b4275aeb834ba4294f2c074dabef Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 10 Nov 2021 08:43:50 +0000 Subject: [PATCH 06/16] chore(deps): update dependency eslint-plugin-import to v2.25.3 --- package.json | 2 +- yarn.lock | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 6b923da9f2..dcc4f22cbe 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,7 @@ "eslint-config-airbnb-base": "14.2.1", "eslint-config-airbnb-typescript": "15.0.0", "eslint-config-prettier": "8.3.0", - "eslint-plugin-import": "2.25.2", + "eslint-plugin-import": "2.25.3", "eslint-plugin-prettier": "4.0.0", "faker": "5.5.3", "fetch-mock": "9.11.0", diff --git a/yarn.lock b/yarn.lock index f2d513ed88..e4da1732ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2495,28 +2495,28 @@ eslint-import-resolver-node@^0.3.6: debug "^3.2.7" resolve "^1.20.0" -eslint-module-utils@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.0.tgz#9e97c12688113401259b39d960e6a1f09f966435" - integrity sha512-hqSE88MmHl3ru9SYvDyGrlo0JwROlf9fiEMplEV7j/EAuq9iSlIlyCFbBT6pdULQBSnBYtYKiMLps+hKkyP7Gg== +eslint-module-utils@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz#b435001c9f8dd4ab7f6d0efcae4b9696d4c24b7c" + integrity sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ== dependencies: debug "^3.2.7" find-up "^2.1.0" pkg-dir "^2.0.0" -eslint-plugin-import@2.25.2: - version "2.25.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.2.tgz#b3b9160efddb702fc1636659e71ba1d10adbe9e9" - integrity sha512-qCwQr9TYfoBHOFcVGKY9C9unq05uOxxdklmBXLVvcwo68y5Hta6/GzCZEMx2zQiu0woKNEER0LE7ZgaOfBU14g== +eslint-plugin-import@2.25.3: + version "2.25.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz#a554b5f66e08fb4f6dc99221866e57cfff824766" + integrity sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg== dependencies: array-includes "^3.1.4" array.prototype.flat "^1.2.5" debug "^2.6.9" doctrine "^2.1.0" eslint-import-resolver-node "^0.3.6" - eslint-module-utils "^2.7.0" + eslint-module-utils "^2.7.1" has "^1.0.3" - is-core-module "^2.7.0" + is-core-module "^2.8.0" is-glob "^4.0.3" minimatch "^3.0.4" object.values "^1.1.5" @@ -3630,10 +3630,10 @@ is-core-module@^2.2.0: dependencies: has "^1.0.3" -is-core-module@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.7.0.tgz#3c0ef7d31b4acfc574f80c58409d568a836848e3" - integrity sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ== +is-core-module@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" + integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== dependencies: has "^1.0.3" From e1df5696cdfa280c886b9ee7c98f9f42178253ef Mon Sep 17 00:00:00 2001 From: Nikolay Shebanov Date: Thu, 11 Nov 2021 13:20:19 +0100 Subject: [PATCH 07/16] Wrap the client into an event listener in the quickstart doc (#1079) --- website/docs/user_guide/quickstart.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/website/docs/user_guide/quickstart.md b/website/docs/user_guide/quickstart.md index eba91e23b1..9fdab31479 100644 --- a/website/docs/user_guide/quickstart.md +++ b/website/docs/user_guide/quickstart.md @@ -46,15 +46,17 @@ const unleash = new UnleashClient({ appName: 'my-webapp', }); +unleash.on('synchronized', () => { + if (unleash.isEnabled('proxy.demo')) { + // do something + } +}); + // Used to set the context fields, shared with the Unleash Proxy unleash.updateContext({ userId: '1233' }); // Start the background polling unleash.start(); - -if (unleash.isEnabled('proxy.demo')) { - // do something -} ``` Now you are ready to use the feature toggle you created in your client side application, using the appropriate proxy SDK. From f2b3325d4232ab67d7cbc35f8c8b94150cc3330c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Nov 2021 14:04:45 +0100 Subject: [PATCH 08/16] chore(deps): update dependency eslint-config-airbnb-base to v15 (#1098) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index dcc4f22cbe..542c8dc8a9 100644 --- a/package.json +++ b/package.json @@ -137,7 +137,7 @@ "coveralls": "3.1.1", "del-cli": "4.0.1", "eslint": "8.2.0", - "eslint-config-airbnb-base": "14.2.1", + "eslint-config-airbnb-base": "15.0.0", "eslint-config-airbnb-typescript": "15.0.0", "eslint-config-prettier": "8.3.0", "eslint-plugin-import": "2.25.3", diff --git a/yarn.lock b/yarn.lock index e4da1732ac..37fc09f14a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2466,7 +2466,17 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-config-airbnb-base@14.2.1, eslint-config-airbnb-base@^14.2.1: +eslint-config-airbnb-base@15.0.0: + version "15.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz#6b09add90ac79c2f8d723a2580e07f3925afd236" + integrity sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig== + dependencies: + confusing-browser-globals "^1.0.10" + object.assign "^4.1.2" + object.entries "^1.1.5" + semver "^6.3.0" + +eslint-config-airbnb-base@^14.2.1: version "14.2.1" resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz#8a2eb38455dc5a312550193b319cdaeef042cd1e" integrity sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA== @@ -5259,6 +5269,15 @@ object.entries@^1.1.2: define-properties "^1.1.3" es-abstract "^1.18.2" +object.entries@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861" + integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + object.map@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz" From 8a417997319baeab4f8e49d25c7bf6844a1ab60e Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Thu, 11 Nov 2021 15:36:41 +0100 Subject: [PATCH 09/16] docs: Polish text on environments. There's a number of small text adjustments and typo fixes in here with the goal of clarifying how environments and the migration process work. --- website/docs/user_guide/environments.md | 63 +++++++++++++------------ 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/website/docs/user_guide/environments.md b/website/docs/user_guide/environments.md index 1bf28fefdf..dd0f1473a9 100644 --- a/website/docs/user_guide/environments.md +++ b/website/docs/user_guide/environments.md @@ -4,7 +4,7 @@ title: Environments ---
@@ -13,13 +13,13 @@ title: Environments -Environments is a new way to organize activation strategy configurations for feature toggles into separate environments. In Unleash a feature lives across all your environments, after all, the goal is to get the new feature released as soon as possible. But it makes sense to configure the activation differently per environment. You might want the feature enabled for everyone in development, while only enable it for yourself in production. +Environments is a new way to organize activation strategy configurations for feature toggles into separate environments. In Unleash, a feature lives across all your environments — after all, the goal is to get the new feature released as soon as possible — but it makes sense to configure the activation differently per environment. You might want the feature enabled for everyone in development, but only for yourself in production, for instance. -Unleash Enterprise users have been able to leverage strategy constraints to control the roll-out per environment. This will not be needed after the release as a "full group" of activation strategy will belong to an environment. +Previously, Unleash Enterprise users have been able to leverage [strategy constraints](../advanced/strategy-constraints) to control the rollout across environments. With the new environments feature, this is no longer necessary. Now all activation strategies belong to an explicit environment instead. -Connected applications will also use environment scoped API keys, to make sure they only download feature toggle configurations for the environment they are running in. +Further, connected applications will use environment-scoped API keys to make sure they only download feature toggle configurations for the environment they are running in. -Metrics has also been upgraded to record the environment, so that Unleash now can display the usage metrics per environment. +Finally, metrics have also been upgraded to record the environment. This, in turn, means that Unleash can display usage metrics per environment. @@ -28,11 +28,11 @@ Metrics has also been upgraded to record the environment, so that Unleash now ca ## How to start using environments -In order to start using environments you need to be on Unleash v4.2. You also need to have the environment feature enabled (if you are using Unleash Hosted, please reach out on [contact@getunleash.io](mailto:contact@getunleash.io) if you want to start using environments. +In order to start using environments you need to be on Unleash v4.2. You also need to have the environment feature enabled (if you are using Unleash Hosted, please reach out on [contact@getunleash.io](mailto:contact@getunleash.io) if you want to start using environments. ### Step 1: Enable new environments for your Project -Navigate to the project and choose the “environments” tab. +Navigate to the project and choose the “environments” tab. @@ -42,7 +42,7 @@ Navigate to the project and choose the “environments” tab. ### Step 2: Configure activation strategies for the new environment -From the “feature toggle view” you will now be able to configure activation strategies per environment. +From the “feature toggle view” you will now be able to configure activation strategies per environment. @@ -51,7 +51,7 @@ From the “feature toggle view” you will now be able to configure activation ### Step 3: Create environment specific API keys -In order for the SDK to download the feature toggle configuration for the correct environment you will need to create an API token for a defined environment. +In order for the SDK to download the feature toggle configuration for the correct environment you will need to create an API token for a defined environment. @@ -61,9 +61,10 @@ In order for the SDK to download the feature toggle configuration for the correc ## Migration -To ease migration we have created a special environment called “default”. All existing activation strategies have been added to this environment. All existing Client API keys has also been scoped to work against the default environment, to ensure zero disruption as part of the upgrade. +To ease migration we have created a special environment called “default”. All existing activation strategies have been added to this environment. All existing Client API keys have also been scoped to work against the default environment to ensure zero disruption as part of the upgrade. + +If you're currently using strategy constraints together with the “environment” field on the Unleash Context, you should be aware that the new environment support works slightly differently. With environments, the SDK API will use the client's API key to determine which environment the client is configured for. The API then sends _only_ strategies belonging to the client's environment. This means that you might not need the "environment" property of the Unleash Context anymore. -If you today are using strategy constraints together with the “environment” field on the Unleash Context you should be aware that the new environment support works slightly differently. Now the SDK will only download the activation strategies configured for a configured environment. The Unleash SDK API will know which environment to deliver to the SDK because the API token used by the SDK is scoped to a single environment. Because of this you will probably stop using “environment” on the Unleash Context. @@ -73,31 +74,33 @@ If you today are using strategy constraints together with the “environment” ### Addons -We have slightly changed the events related to working with feature toggles. This means that you would need to change your addon configuration to also subscribe for the new events to not miss updates: +We have made some slight changes to events related to feature toggles: there's one deprecation and several new event types. Most of the new events contain _project_ and _environment_ data. + +To avoid missing important updates, you will also need to update your addon configuration to subscribe to the new events. **Deprecated events:** * **FEATURE_UPDATE** - _not used after switching to environments_ **New Events** -* **FEATURE-METADATA-UPDATED** - The feature toggle metadata was updated (across all environments). +* **FEATURE-METADATA-UPDATED** - The feature toggle metadata was updated (across all environments). * **FEATURE-STRATEGY-ADD**¹ - An activation strategy was added to a feature toggle in an environment. The _data_ will contain the updated strategy configuration. * **FEATURE-STRATEGY-UPDATE**¹ - An activation strategy was updated for a feature toggle. The _data_ will contain the updated strategy configuration. -* **FEATURE-STRATEGY-REMOVE**¹ - An activation strategy was removed for a feature toggle. -* **FEATURE-ENVIRONMENT-ENABLED**¹ - Signals that a feature toggle has been _enabled_ in a defined environment. -* **FEATURE-ENVIRONMENT-DISABLED**¹ - Signals that a feature toggle has been _disabled_ in a defined environment. -* **FEATURE-PROJECT-CHANGE**¹ - The feature toggle was moved to a new project. +* **FEATURE-STRATEGY-REMOVE**¹ - An activation strategy was removed for a feature toggle. +* **FEATURE-ENVIRONMENT-ENABLED**¹ - Signals that a feature toggle has been _enabled_ in a defined environment. +* **FEATURE-ENVIRONMENT-DISABLED**¹ - Signals that a feature toggle has been _disabled_ in a defined environment. +* **FEATURE-PROJECT-CHANGE**¹ - The feature toggle was moved to a new project. -> 1) These feature events will contain _project_ and _environment_ as part of the even metadata. +> 1) These feature events will contain _project_ and _environment_ as part of the event metadata. -### API +### API -In order to support configuration per environment we had to rebuild our feature toggle admin API to account for environments as well. This means +In order to support configuration per environment we had to rebuild our feature toggle admin API to account for environments as well. This means that we're making the following changes to the API: * **/api/admin/features** - _deprecated (scheduled for removal in Unleash v5.0). The [old feature toggles admin API](https://docs.getunleash.io/api/admin/features) still works, but strategy configuration will be assumed to target the “default” environment._ -* **/api/admin/projects/:projectId/features** - New feature API to be used for feature toggles which also adds support for environments. See [the documentation](https://docs.getunleash.io/api/admin/feature-toggles-v2) to learn more. +* **/api/admin/projects/:projectId/features** - New feature API to be used for feature toggles which also adds support for environments. See [the documentation](https://docs.getunleash.io/api/admin/feature-toggles-v2) to learn more. ## Plan Differences @@ -107,23 +110,23 @@ In order to support configuration per environment we had to rebuild our feature -* Will get access to two pre-configured environments: “development” and “production”. Existing users of Unleash will also get an additional “default” environment to simplify adoption of environments. -* Will be possible to turn environments on/off for all projects. +* Will get access to two pre-configured environments: “development” and “production”. Existing users of Unleash will also get an additional “default” environment to simplify adoption of environments. +* Will be possible to turn environments on/off for all projects. ### Pro (commercial) -* Will get access to two pre-configured environments: “development” and “production”. Existing users of Unleash will also get an additional “default” environment to simplify the adoption of environments. -* Will be possible to turn environments on/off for the default project. +* Will get access to two pre-configured environments: “development” and “production”. Existing users of Unleash will also get an additional “default” environment to simplify the adoption of environments. +* Will be possible to turn environments on/off for the default project. ### Enterprise (commercial) -* Will get access to two pre-configured environments: “development” and “production”. Existing users of Unleash will also get an additional “default” environment to simplify the adoption of environments. +* Will get access to two pre-configured environments: “development” and “production”. Existing users of Unleash will also get an additional “default” environment to simplify the adoption of environments. * Will be possible to turn environments on/off for all projects * Will be allowed to update and remove environments. * Will be allowed to create new environments. @@ -133,8 +136,8 @@ In order to support configuration per environment we had to rebuild our feature -* **Unleash v4.2** will provide _early access_ to environment support. This means that it can be enabled per customer via a feature flag. -* **Unleash v4.3** plans to provide general access to the environment support for all users of Unleash (Open-Source, Pro, Enterprise). +* **Unleash v4.2** will provide _early access_ to environment support. This means that it can be enabled per customer via a feature flag. +* **Unleash v4.3** plans to provide general access to the environment support for all users of Unleash (Open-Source, Pro, Enterprise). ### Future enhancements @@ -143,5 +146,5 @@ With improved environment capabilities we have also done the groundwork to be ab -* Improve **Usage Metrics **to be able to show usage and evaluation results per hour for multiple days with dimensions such as environment, application and time (per hour). -* Improve **RBAC** with the ability to limit who can change configuration for a specific environment (planned as an enterprise feature). \ No newline at end of file +* Improve **Usage Metrics** to be able to show usage and evaluation results per hour for multiple days with dimensions such as environment, application and time (per hour). +* Improve **RBAC** with the ability to limit who can change configuration for a specific environment (planned as an enterprise feature). From 257497153c0ceaadb73eb6c8405b363b1656859e Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Thu, 11 Nov 2021 15:41:54 +0100 Subject: [PATCH 10/16] Use absolute URL for intra-doc link. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I don't know how this works in docusaurus 🤷 --- website/docs/user_guide/environments.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/user_guide/environments.md b/website/docs/user_guide/environments.md index dd0f1473a9..28cd1ea7bf 100644 --- a/website/docs/user_guide/environments.md +++ b/website/docs/user_guide/environments.md @@ -15,7 +15,7 @@ title: Environments Environments is a new way to organize activation strategy configurations for feature toggles into separate environments. In Unleash, a feature lives across all your environments — after all, the goal is to get the new feature released as soon as possible — but it makes sense to configure the activation differently per environment. You might want the feature enabled for everyone in development, but only for yourself in production, for instance. -Previously, Unleash Enterprise users have been able to leverage [strategy constraints](../advanced/strategy-constraints) to control the rollout across environments. With the new environments feature, this is no longer necessary. Now all activation strategies belong to an explicit environment instead. +Previously, Unleash Enterprise users have been able to leverage [strategy constraints](https://docs.getunleash.io/advanced/strategy_constraints) to control the rollout across environments. With the new environments feature, this is no longer necessary. Now all activation strategies belong to an explicit environment instead. Further, connected applications will use environment-scoped API keys to make sure they only download feature toggle configurations for the environment they are running in. From f0895cf653799741e4f539639976b22f941daab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20Conradi=20=C3=98sthus?= Date: Thu, 11 Nov 2021 16:05:29 +0100 Subject: [PATCH 11/16] fix: prevent deadlock for batchinserting usage metrics (#1100) * fix: prevent deadlock for batchinserting usage metrics In client metrics v2 we utilize postgres to count the usage across a few dimentions (featureName, app_name, environment). It turns out that if the UPDATE values are not executed in a predictable order we can end up in a deadlock scenario with postgresql. In this fix we thus sort the metrics on the feature_name, app_name and envrionment, to make sure they always are executed in a predictabel order, and thus avoiding independent inserts colliding in to a deadlock waiting for eachother. * fix: tests cannot assume order --- src/lib/db/client-metrics-store-v2.ts | 10 +++++- .../e2e/api/admin/client-metrics.e2e.test.ts | 34 ++++++++++++------- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/lib/db/client-metrics-store-v2.ts b/src/lib/db/client-metrics-store-v2.ts index dfc8494f52..357457697b 100644 --- a/src/lib/db/client-metrics-store-v2.ts +++ b/src/lib/db/client-metrics-store-v2.ts @@ -116,9 +116,17 @@ export class ClientMetricsStoreV2 implements IClientMetricsStoreV2 { return prev; }, {}); + // Sort the rows to avoid deadlocks + const batchRow = Object.values(batch).sort( + (a, b) => + a.feature_name.localeCompare(b.feature_name) || + a.app_name.localeCompare(b.app_name) || + a.environment.localeCompare(b.environment), + ); + // Consider rewriting to SQL batch! const insert = this.db(TABLE) - .insert(Object.values(batch)) + .insert(batchRow) .toQuery(); const query = `${insert.toString()} ON CONFLICT (feature_name, app_name, environment, timestamp) DO UPDATE SET "yes" = "client_metrics_env"."yes" + EXCLUDED.yes, "no" = "client_metrics_env"."no" + EXCLUDED.no`; diff --git a/src/test/e2e/api/admin/client-metrics.e2e.test.ts b/src/test/e2e/api/admin/client-metrics.e2e.test.ts index 6558c076a8..f9f2ad7680 100644 --- a/src/test/e2e/api/admin/client-metrics.e2e.test.ts +++ b/src/test/e2e/api/admin/client-metrics.e2e.test.ts @@ -155,14 +155,19 @@ test('should return toggle summary', async () => { .expect('Content-Type', /json/) .expect(200); + const test = demo.lastHourUsage.find((u) => u.environment === 'test'); + const defaultEnv = demo.lastHourUsage.find( + (u) => u.environment === 'default', + ); + expect(demo.featureName).toBe('demo'); expect(demo.lastHourUsage).toHaveLength(2); - expect(demo.lastHourUsage[0].environment).toBe('default'); - expect(demo.lastHourUsage[0].yes).toBe(5); - expect(demo.lastHourUsage[0].no).toBe(4); - expect(demo.lastHourUsage[1].environment).toBe('test'); - expect(demo.lastHourUsage[1].yes).toBe(2); - expect(demo.lastHourUsage[1].no).toBe(6); + expect(test.environment).toBe('test'); + expect(test.yes).toBe(2); + expect(test.no).toBe(6); + expect(defaultEnv.environment).toBe('default'); + expect(defaultEnv.yes).toBe(5); + expect(defaultEnv.no).toBe(4); expect(demo.seenApplications).toStrictEqual(['backend-api', 'web']); }); @@ -219,13 +224,18 @@ test('should only include last hour of metrics return toggle summary', async () .expect('Content-Type', /json/) .expect(200); + const test = demo.lastHourUsage.find((u) => u.environment === 'test'); + const defaultEnv = demo.lastHourUsage.find( + (u) => u.environment === 'default', + ); + expect(demo.featureName).toBe('demo'); expect(demo.lastHourUsage).toHaveLength(2); - expect(demo.lastHourUsage[0].environment).toBe('default'); - expect(demo.lastHourUsage[0].yes).toBe(5); - expect(demo.lastHourUsage[0].no).toBe(4); - expect(demo.lastHourUsage[1].environment).toBe('test'); - expect(demo.lastHourUsage[1].yes).toBe(2); - expect(demo.lastHourUsage[1].no).toBe(6); + expect(defaultEnv.environment).toBe('default'); + expect(defaultEnv.yes).toBe(5); + expect(defaultEnv.no).toBe(4); + expect(test.environment).toBe('test'); + expect(test.yes).toBe(2); + expect(test.no).toBe(6); expect(demo.seenApplications).toStrictEqual(['backend-api', 'web']); }); From 064599c942011b2827ae497f9d03974494537d22 Mon Sep 17 00:00:00 2001 From: Martin Lehmann Date: Thu, 11 Nov 2021 20:29:40 +0100 Subject: [PATCH 12/16] fix: refactor client-metrics list and ttl-list to TypeScript (#1080) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ivar Conradi Østhus --- src/lib/services/client-metrics/index.ts | 7 +-- .../{list.test.js => list.test.ts} | 6 +-- .../client-metrics/{list.js => list.ts} | 34 +++++++++----- .../{ttl-list.test.js => ttl-list.test.ts} | 12 +++-- .../{ttl-list.js => ttl-list.ts} | 45 +++++++++++++------ 5 files changed, 64 insertions(+), 40 deletions(-) rename src/lib/services/client-metrics/{list.test.js => list.test.ts} (97%) rename src/lib/services/client-metrics/{list.js => list.ts} (82%) rename src/lib/services/client-metrics/{ttl-list.test.js => ttl-list.test.ts} (90%) rename src/lib/services/client-metrics/{ttl-list.js => ttl-list.ts} (66%) diff --git a/src/lib/services/client-metrics/index.ts b/src/lib/services/client-metrics/index.ts index 874261eff4..1b7fd49498 100644 --- a/src/lib/services/client-metrics/index.ts +++ b/src/lib/services/client-metrics/index.ts @@ -22,12 +22,13 @@ import { IMetricsBucket, } from '../../types/model'; import { clientRegisterSchema } from './register-schema'; + import { minutesToMilliseconds, parseISO, secondsToMilliseconds, } from 'date-fns'; -import TTLList = require('./ttl-list'); +import TTLList from './ttl-list'; export default class ClientMetricsService { globalCount = 0; @@ -38,13 +39,13 @@ export default class ClientMetricsService { lastMinuteProjection = new Projection(); - lastHourList = new TTLList({ + lastHourList = new TTLList({ interval: secondsToMilliseconds(10), }); logger = null; - lastMinuteList = new TTLList({ + lastMinuteList = new TTLList({ interval: secondsToMilliseconds(10), expireType: 'minutes', expireAmount: 1, diff --git a/src/lib/services/client-metrics/list.test.js b/src/lib/services/client-metrics/list.test.ts similarity index 97% rename from src/lib/services/client-metrics/list.test.js rename to src/lib/services/client-metrics/list.test.ts index 73a30e45fa..1eb1c0fdf5 100644 --- a/src/lib/services/client-metrics/list.test.js +++ b/src/lib/services/client-metrics/list.test.ts @@ -1,9 +1,7 @@ -'use strict'; - -const List = require('./list'); +import List from './list'; function getList() { - const list = new List(); + const list = new List(); list.add(1); list.add(2); list.add(3); diff --git a/src/lib/services/client-metrics/list.js b/src/lib/services/client-metrics/list.ts similarity index 82% rename from src/lib/services/client-metrics/list.js rename to src/lib/services/client-metrics/list.ts index e0829352de..8a1d55eccf 100644 --- a/src/lib/services/client-metrics/list.js +++ b/src/lib/services/client-metrics/list.ts @@ -1,31 +1,41 @@ /* eslint-disable no-param-reassign */ /* eslint-disable max-classes-per-file */ -'use strict'; +import { EventEmitter } from 'events'; -const { EventEmitter } = require('events'); +class Node { + value: T | null; -class Node { - constructor(value) { + prev: Node | null; + + next: Node | null; + + constructor(value: T) { this.value = value; this.next = null; } - link(next) { + link(next: Node) { this.next = next; next.prev = this; return this; } } -module.exports = class List extends EventEmitter { +type IteratorFn = (cursor: Node) => U; + +export default class List extends EventEmitter { + private start: Node | null; + + private tail: Node | null; + constructor() { super(); this.start = null; this.tail = null; } - add(obj) { + add(obj: T): Node { const node = new Node(obj); if (this.start) { this.start = node.link(this.start); @@ -36,7 +46,7 @@ module.exports = class List extends EventEmitter { return node; } - iterate(fn) { + iterate(fn: IteratorFn): void { if (!this.start) { return; } @@ -51,7 +61,7 @@ module.exports = class List extends EventEmitter { } } - iterateReverse(fn) { + iterateReverse(fn: IteratorFn): void { if (!this.tail) { return; } @@ -66,7 +76,7 @@ module.exports = class List extends EventEmitter { } } - reverseRemoveUntilTrue(fn) { + reverseRemoveUntilTrue(fn: IteratorFn): void { if (!this.tail) { return; } @@ -98,7 +108,7 @@ module.exports = class List extends EventEmitter { } } - toArray() { + toArray(): T[] { const result = []; if (this.start) { @@ -125,4 +135,4 @@ module.exports = class List extends EventEmitter { // return result; // } -}; +} diff --git a/src/lib/services/client-metrics/ttl-list.test.js b/src/lib/services/client-metrics/ttl-list.test.ts similarity index 90% rename from src/lib/services/client-metrics/ttl-list.test.js rename to src/lib/services/client-metrics/ttl-list.test.ts index fc4d39d20b..e2349b2804 100644 --- a/src/lib/services/client-metrics/ttl-list.test.js +++ b/src/lib/services/client-metrics/ttl-list.test.ts @@ -1,11 +1,9 @@ -'use strict'; - -const TTLList = require('./ttl-list'); -const { addMilliseconds } = require('date-fns'); +import { addMilliseconds } from 'date-fns'; +import TTLList from './ttl-list'; test('should emit expire', (done) => { jest.useFakeTimers('modern'); - const list = new TTLList({ + const list = new TTLList<{ n: number }>({ interval: 20, expireAmount: 10, expireType: 'milliseconds', @@ -25,7 +23,7 @@ test('should emit expire', (done) => { test('should slice off list', () => { jest.useFakeTimers('modern'); - const list = new TTLList({ + const list = new TTLList<{ n: string }>({ interval: 10, expireAmount: 10, expireType: 'milliseconds', @@ -69,7 +67,7 @@ test('should slice off list', () => { test('should add item created in the past but expiring in the future', () => { jest.useFakeTimers('modern'); - const list = new TTLList({ + const list = new TTLList<{ n: string }>({ interval: 10, expireAmount: 10, expireType: 'milliseconds', diff --git a/src/lib/services/client-metrics/ttl-list.js b/src/lib/services/client-metrics/ttl-list.ts similarity index 66% rename from src/lib/services/client-metrics/ttl-list.js rename to src/lib/services/client-metrics/ttl-list.ts index e81538cb30..a09bffe9f2 100644 --- a/src/lib/services/client-metrics/ttl-list.js +++ b/src/lib/services/client-metrics/ttl-list.ts @@ -1,21 +1,38 @@ -'use strict'; - -const { EventEmitter } = require('events'); -const List = require('./list'); -const { +import { EventEmitter } from 'events'; +import List from './list'; +import { add, - isFuture, addMilliseconds, secondsToMilliseconds, -} = require('date-fns'); + Duration, + isFuture, +} from 'date-fns'; + +interface ConstructorArgs { + interval: number; + expireAmount: number; + expireType: keyof Duration | 'milliseconds'; +} // this list must have entries with sorted ttl range -module.exports = class TTLList extends EventEmitter { +export default class TTLList extends EventEmitter { + private readonly interval: number; + + private readonly expireAmount: number; + + private readonly expireType: keyof Duration | 'milliseconds'; + + public list: List<{ ttl: Date; value: T }>; + + private timer: NodeJS.Timeout; + + private readonly getExpiryFrom: (timestamp) => Date; + constructor({ interval = secondsToMilliseconds(1), expireAmount = 1, expireType = 'hours', - } = {}) { + }: Partial = {}) { super(); this.interval = interval; this.expireAmount = expireAmount; @@ -37,7 +54,7 @@ module.exports = class TTLList extends EventEmitter { this.startTimer(); } - startTimer() { + startTimer(): void { if (this.list) { this.timer = setTimeout(() => { if (this.list) { @@ -48,7 +65,7 @@ module.exports = class TTLList extends EventEmitter { } } - add(value, timestamp = new Date()) { + add(value: T, timestamp = new Date()): void { const ttl = this.getExpiryFrom(timestamp); if (isFuture(ttl)) { this.list.add({ ttl, value }); @@ -57,14 +74,14 @@ module.exports = class TTLList extends EventEmitter { } } - timedCheck() { + timedCheck(): void { this.list.reverseRemoveUntilTrue(({ value }) => isFuture(value.ttl)); this.startTimer(); } - destroy() { + destroy(): void { clearTimeout(this.timer); this.timer = null; this.list = null; } -}; +} From b7769841877a373274fffc2035425c14c119fd8d Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Fri, 12 Nov 2021 08:25:55 +0100 Subject: [PATCH 13/16] docs: simplify language + pre-configure -> preconfigure --- website/docs/user_guide/environments.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docs/user_guide/environments.md b/website/docs/user_guide/environments.md index 28cd1ea7bf..1fd7eb0acb 100644 --- a/website/docs/user_guide/environments.md +++ b/website/docs/user_guide/environments.md @@ -15,7 +15,7 @@ title: Environments Environments is a new way to organize activation strategy configurations for feature toggles into separate environments. In Unleash, a feature lives across all your environments — after all, the goal is to get the new feature released as soon as possible — but it makes sense to configure the activation differently per environment. You might want the feature enabled for everyone in development, but only for yourself in production, for instance. -Previously, Unleash Enterprise users have been able to leverage [strategy constraints](https://docs.getunleash.io/advanced/strategy_constraints) to control the rollout across environments. With the new environments feature, this is no longer necessary. Now all activation strategies belong to an explicit environment instead. +Previously, Unleash Enterprise could use [strategy constraints](https://docs.getunleash.io/advanced/strategy_constraints) to control the rollout across environments. With the new environments feature, this is no longer necessary. Now all activation strategies belong to an explicit environment instead. Further, connected applications will use environment-scoped API keys to make sure they only download feature toggle configurations for the environment they are running in. @@ -110,7 +110,7 @@ In order to support configuration per environment we had to rebuild our feature -* Will get access to two pre-configured environments: “development” and “production”. Existing users of Unleash will also get an additional “default” environment to simplify adoption of environments. +* Will get access to two preconfigured environments: “development” and “production”. Existing users of Unleash will also get an additional “default” environment to simplify the adoption of environments. * Will be possible to turn environments on/off for all projects. @@ -118,7 +118,7 @@ In order to support configuration per environment we had to rebuild our feature -* Will get access to two pre-configured environments: “development” and “production”. Existing users of Unleash will also get an additional “default” environment to simplify the adoption of environments. +* Will get access to two preconfigured environments: “development” and “production”. Existing users of Unleash will also get an additional “default” environment to simplify the adoption of environments. * Will be possible to turn environments on/off for the default project. @@ -126,7 +126,7 @@ In order to support configuration per environment we had to rebuild our feature -* Will get access to two pre-configured environments: “development” and “production”. Existing users of Unleash will also get an additional “default” environment to simplify the adoption of environments. +* Will get access to two preconfigured environments: “development” and “production”. Existing users of Unleash will also get an additional “default” environment to simplify the adoption of environments. * Will be possible to turn environments on/off for all projects * Will be allowed to update and remove environments. * Will be allowed to create new environments. From 854f2d5d651264122de5352184abafe963f322d6 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Fri, 12 Nov 2021 08:26:19 +0100 Subject: [PATCH 14/16] docs: add paragraph to intro: things will still work (default env) --- website/docs/user_guide/environments.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/docs/user_guide/environments.md b/website/docs/user_guide/environments.md index 1fd7eb0acb..6bfb5b9f9e 100644 --- a/website/docs/user_guide/environments.md +++ b/website/docs/user_guide/environments.md @@ -21,6 +21,8 @@ Further, connected applications will use environment-scoped API keys to make sur Finally, metrics have also been upgraded to record the environment. This, in turn, means that Unleash can display usage metrics per environment. +Despite this being a shift in how Unleash works, everything will continue to work exactly how it did for existing users. For backwards compatibility, we have created an environment named "default" that will contain all of the existing toggles and API keys. Read more about that in [the migration section](#migration). + ![Environments Overview](/img/environments_overview.svg "A feature toggle exists across all environments, but take different activation strategies per environment.") From 77890bf88acb888f3ffab4bdcbded7210db698c1 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Fri, 12 Nov 2021 08:33:55 +0100 Subject: [PATCH 15/16] docs: add notes about users having to add strats to enable envs. --- website/docs/user_guide/environments.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/website/docs/user_guide/environments.md b/website/docs/user_guide/environments.md index 6bfb5b9f9e..f7ee615bf7 100644 --- a/website/docs/user_guide/environments.md +++ b/website/docs/user_guide/environments.md @@ -30,7 +30,9 @@ Despite this being a shift in how Unleash works, everything will continue to wor ## How to start using environments -In order to start using environments you need to be on Unleash v4.2. You also need to have the environment feature enabled (if you are using Unleash Hosted, please reach out on [contact@getunleash.io](mailto:contact@getunleash.io) if you want to start using environments. +In order to start using environments you need to be on Unleash v4.2 or higher. You also need to have the environment feature enabled (if you are using Unleash Hosted, please reach out on [contact@getunleash.io](mailto:contact@getunleash.io) if you want to start using environments. + +Note that in order to enable an environment for a feature toggle, you must first add activation strategies for that environment. You cannot enable an environment without activation strategies. ### Step 1: Enable new environments for your Project @@ -44,7 +46,7 @@ Navigate to the project and choose the “environments” tab. ### Step 2: Configure activation strategies for the new environment -From the “feature toggle view” you will now be able to configure activation strategies per environment. +From the “feature toggle view” you will now be able to configure activation strategies per environment. You can also enable and disable environments here. Remember that an environment must have activation strategies before you can enable it. From 7409f679f2cf83fe396d74ac7ccd54e87a548875 Mon Sep 17 00:00:00 2001 From: Christopher Kolstad Date: Fri, 12 Nov 2021 08:34:00 +0100 Subject: [PATCH 16/16] docs: Updated maven coordinates for java sdk --- website/docs/sdks/java.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/sdks/java.md b/website/docs/sdks/java.md index 5f567a5671..978a92670a 100644 --- a/website/docs/sdks/java.md +++ b/website/docs/sdks/java.md @@ -13,7 +13,7 @@ First we must add Unleash Client SDK as a dependency to your project. Below is a ```xml - no.finn.unleash + io.getunleash unleash-client-java Latest version here