From 0b5b74ebaba9462b5958d182522de85dc9529b8d Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Mon, 7 Mar 2022 15:39:32 +0100 Subject: [PATCH 01/19] docs: start scaffolding out new constraint operator info --- website/docs/advanced/strategy-constraints.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/website/docs/advanced/strategy-constraints.md b/website/docs/advanced/strategy-constraints.md index 162a02cdc3..efc402b1bb 100644 --- a/website/docs/advanced/strategy-constraints.md +++ b/website/docs/advanced/strategy-constraints.md @@ -20,6 +20,71 @@ Combining strategy constraints with the [gradual rollout strategy](../user_guide ![A toggle with the gradual rollout strategy. The toggle is constrained on the custom content field "region" and set to only activate if the region is Africa or Europe.](/img/custom-constraints.png) +## Strategy constraint operators + +Unleash currently supports 15 different constraint operators. +The operators can be grouped into four different categories based on their method of comparison. + +All operators can be **negated**, meaning that they get their opposite value + +Each operator is evaluated such that ` ` + +### Numeric operators + +| Name | Description | +|-----------|----------------------------------------------------------| +| `NUM_EQ` | Numerical equivalence; the mathematical `=` operator. | +| `NUM_GT` | Strictly greater than; the mathematical `>` operator. | +| `NUM_GTE` | Greater than or equal to; the mathematical `⩾` operator. | +| `NUM_LT` | Strictly less than; the mathematical `<` operator. | +| `NUM_LTE` | Less than or equal to; the mathematical `⩽` operator. | + +You can read more about [numeric equality](https://en.wikipedia.org/wiki/Equality_(mathematics) "Mathematical equality at Wikipedia") or [numeric inequality operators at Wikipedia](https://en.wikipedia.org/wiki/Inequality_(mathematics)). + +### Date and time operators + +:::info Context field availability +The date and time operators are **only available on the `currentTime`** context field. +::: + +With the date and time operators, you can enable a feature before and/or after a specified time. +They compare the [Unleash context's](../user_guide/unleash_context) `currentTime` property. + +You can combine the two constraint operators by setting two separate constraints on a single strategy to create a time span. +In that case the strategy will be evaluated from `DATE_AFTER` and until `DATE_BEFORE`. + +| Name | Description | +|---------------|---------------------------------------------------------------------| +| `DATE_AFTER` | Will evaluate to true if `currentTime` is after the provided date. | +| `DATE_BEFORE` | Will evaluate to true if `currentTime` is before the provided date. | + +### String operators + +String operators are all multi-value and most can be either case sensitive or insensitive + +:::note +For legacy reasons / backwards compatibility, `IN` and `NOT_IN` are always case sensitive. +::: + +| Name | Available since | Description | +|-------------------|-----------------|-------------| +| `IN` | 3.3 | | +| `NOT_IN` | 3.3 | | +| `STR_CONTAINS` | 4.9 | Does the string contain any of the provided strings? | +| `STR_ENDS_WITH` | 4.9 | Does the string end with | +| `STR_STARTS_WITH` | 4.9 | | + + +### Versioning (semver) operators + +Versions with pre-release indicators (e.g. `4.8.0-rc.2`) are considered less than versions without (e.g. `4.8.0`) in accordance with [the SemVer specification](https://semver.org/#spec-item-11). + +| Name | Description | +|-------------|---------------------------------------------------------| +| `SEMVER_EQ` | Are the two versions identical? | +| `SEMVER_GT` | Is strictly greater than the provided version | +| `SEMVER_LT` | Is strictly less than the provided version | + ## Constraint structure Each strategy constraint has three parts: From 1b19cac3fa1390d483bb5a402fa57729cde53b9b Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Mon, 7 Mar 2022 17:00:45 +0100 Subject: [PATCH 02/19] docs: add description of each of the strat constraint operators. --- website/docs/advanced/strategy-constraints.md | 68 ++++++++++++------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/website/docs/advanced/strategy-constraints.md b/website/docs/advanced/strategy-constraints.md index efc402b1bb..843e6e62ef 100644 --- a/website/docs/advanced/strategy-constraints.md +++ b/website/docs/advanced/strategy-constraints.md @@ -25,19 +25,31 @@ Combining strategy constraints with the [gradual rollout strategy](../user_guide Unleash currently supports 15 different constraint operators. The operators can be grouped into four different categories based on their method of comparison. -All operators can be **negated**, meaning that they get their opposite value +Each operator forms a predicate together with the provided context field. + +Each operator forms an expression of the form ` ` + +### Negation / inverse values + +All operators can be **negated**, meaning that they get their opposite value. Constraints are evaluated to either `true` or `false`. Negating an operator would turn a `true` into a `false` and a `false` value into a `true` value. + +For instance, using the numeric equivalence operator `NUM_EQ`, the following truth table shows the how value negation affects the result: + +| Expression | Value | Negated | +|--------------|---------|---------| +| 4 `NUM_EQ` 4 | `true` | `false` | +| 4 `NUM_EQ` 5 | `false` | `true` | -Each operator is evaluated such that ` ` ### Numeric operators -| Name | Description | -|-----------|----------------------------------------------------------| -| `NUM_EQ` | Numerical equivalence; the mathematical `=` operator. | -| `NUM_GT` | Strictly greater than; the mathematical `>` operator. | -| `NUM_GTE` | Greater than or equal to; the mathematical `⩾` operator. | -| `NUM_LT` | Strictly less than; the mathematical `<` operator. | -| `NUM_LTE` | Less than or equal to; the mathematical `⩽` operator. | +| Name | `true` if `` is ... | +|-----------|-----------------------------------------------------------------------------| +| `NUM_EQ` | **equal** to the provided value; the mathematical `=` operator | +| `NUM_GT` | **strictly greater than** the provided value; the mathematical `>` operator | +| `NUM_GTE` | **greater than or equal to** the provided value; the mathematical `⩾` operator | +| `NUM_LT` | **strictly less than** the provided value; the mathematical `<` operator | +| `NUM_LTE` | **less than or equal to** the provided value; the mathematical `⩽` operator | You can read more about [numeric equality](https://en.wikipedia.org/wiki/Equality_(mathematics) "Mathematical equality at Wikipedia") or [numeric inequality operators at Wikipedia](https://en.wikipedia.org/wiki/Inequality_(mathematics)). @@ -53,37 +65,41 @@ They compare the [Unleash context's](../user_guide/unleash_context) `currentTime You can combine the two constraint operators by setting two separate constraints on a single strategy to create a time span. In that case the strategy will be evaluated from `DATE_AFTER` and until `DATE_BEFORE`. -| Name | Description | -|---------------|---------------------------------------------------------------------| -| `DATE_AFTER` | Will evaluate to true if `currentTime` is after the provided date. | -| `DATE_BEFORE` | Will evaluate to true if `currentTime` is before the provided date. | +| Name | `true` if `currentTime` is ... | +|---------------|--------------------------------| +| `DATE_AFTER` | **after** the provided date | +| `DATE_BEFORE` | **before** the provided date | ### String operators String operators are all multi-value and most can be either case sensitive or insensitive -:::note +:::note Legacy note For legacy reasons / backwards compatibility, `IN` and `NOT_IN` are always case sensitive. + +`IN` and `NOT_IN` are also each other's inverses. ::: -| Name | Available since | Description | -|-------------------|-----------------|-------------| -| `IN` | 3.3 | | -| `NOT_IN` | 3.3 | | -| `STR_CONTAINS` | 4.9 | Does the string contain any of the provided strings? | -| `STR_ENDS_WITH` | 4.9 | Does the string end with | -| `STR_STARTS_WITH` | 4.9 | | +In the below table, `` is used to indicate that the value of ... + +| Name | Available since | `true` if `` ... | +|-------------------|-----------------|------------------------------------------------| +| `IN` | 3.3 | is **equal** to any of the provided values | +| `NOT_IN` | 3.3 | is **not equal** to any of the provided values | +| `STR_CONTAINS` | 4.9 | **contains** any of the provided strings | +| `STR_ENDS_WITH` | 4.9 | **ends** with any of the provided strings | +| `STR_STARTS_WITH` | 4.9 | **starts** with any of the provided strings | ### Versioning (semver) operators Versions with pre-release indicators (e.g. `4.8.0-rc.2`) are considered less than versions without (e.g. `4.8.0`) in accordance with [the SemVer specification](https://semver.org/#spec-item-11). -| Name | Description | -|-------------|---------------------------------------------------------| -| `SEMVER_EQ` | Are the two versions identical? | -| `SEMVER_GT` | Is strictly greater than the provided version | -| `SEMVER_LT` | Is strictly less than the provided version | +| Name | `true` if `` is ... | +|-------------|----------------------------------------------| +| `SEMVER_EQ` | **equal** to the provided value | +| `SEMVER_GT` | **strictly greater than** the provided value | +| `SEMVER_LT` | **strictly less than** the provided value | ## Constraint structure From 731d1374e137e90ab1f347496272f82179944467 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Mon, 7 Mar 2022 17:21:25 +0100 Subject: [PATCH 03/19] docs: update "constraint structure" section --- website/docs/advanced/strategy-constraints.md | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/website/docs/advanced/strategy-constraints.md b/website/docs/advanced/strategy-constraints.md index 843e6e62ef..d861f1d563 100644 --- a/website/docs/advanced/strategy-constraints.md +++ b/website/docs/advanced/strategy-constraints.md @@ -20,6 +20,24 @@ Combining strategy constraints with the [gradual rollout strategy](../user_guide ![A toggle with the gradual rollout strategy. The toggle is constrained on the custom content field "region" and set to only activate if the region is Africa or Europe.](/img/custom-constraints.png) +## Constraint structure + +Each strategy constraint has three parts: + +- a **context field**: The context field to use for evaluation. +- an **operator**: One of the [operators listed below](#strategy-constraint-operators). +- a **value**/**list of values**: A value or list of values to use in the evaluation of the constraint. + +These parts turn the strategy constraint into an expression that evaluates to either `true` or `false`. + +To clarify, here's a few example strategy constraints and what they do: + +| Context field | Operator | Value(s) | Description | +|-----------------|-----------------|--------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------| +| `userId` | `STR_ENDS_WITH` | `@example.com, @mycompany.com` | Evaluates to `true` for users whose user IDs end with `@example.com` or `@mycompany.com`. | +| `currentTime` | `DATE_AFTER` | `2022-06-05 21:43:22Z` | Evaluates to `true` if the current time is after `2022-06-05 21:43:22Z`. | +| `userScore`[^1] | `NUM_GTE` | `1000` | Evaluates to `true` if the [custom context field](../user_guide/unleash_context#custom-context-fields) `userScore` has a value of `1000` or higher. | + ## Strategy constraint operators Unleash currently supports 15 different constraint operators. @@ -101,19 +119,6 @@ Versions with pre-release indicators (e.g. `4.8.0-rc.2`) are considered less tha | `SEMVER_GT` | **strictly greater than** the provided value | | `SEMVER_LT` | **strictly less than** the provided value | -## Constraint structure - -Each strategy constraint has three parts: - -- **Context field**: The context field to evaluate. -- **Operator**: Either `IN` or `NOT_IN`. -- **Values**: The list of values that trigger this constraint. - -The **context field** is the field that you want to use for constraining this strategy. The **values** field is a list of values that the constraint should either allow or deny. The **operator** determines whether the values are allowed or denied. - -For instance, to constrain the strategy to only users with IDs `id-123` and `id-456`: select `userId` as the context field, use the `IN` operator, and set values to `id-123, id-456`. The strategy will then be evaluated only for these two users. - -If, on the other hand, you would like to ensure the strategy is never evaluated for the same users, you would use the same configuration as above, but set the operator to `NOT_IN`. This would mean that the strategy is evaluated for all users _not_ listed in the values. ## Interacting with strategy constraints in the client SDKs {#sdks} @@ -135,3 +140,5 @@ To be able to constrain on a field, it must be listed under the Context Field me ## [Deprecated]: Constrain on a specific environment {#constrain-on-a-specific-environment} Before Unleash 4.3, using strategy constraints was the recommended way to have different toggle configurations per environment. Now that Unleash has environment support built in, we no longer recommend you use strategy constraints for this. Instead, see the [environments documentation](../user_guide/environments). + +[^1]: `userScore` is not a default Unleash field, but can be added as a [custom context field](../user_guide/unleash_context#custom-context-fields). From 3f5e8524d347a6124b71432541643b858ee6bd32 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Mon, 7 Mar 2022 18:25:41 +0100 Subject: [PATCH 04/19] docs: add availability note, finish first draft of constraint ops --- website/docs/advanced/strategy-constraints.md | 67 +++++++++++-------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/website/docs/advanced/strategy-constraints.md b/website/docs/advanced/strategy-constraints.md index d861f1d563..73c6c33016 100644 --- a/website/docs/advanced/strategy-constraints.md +++ b/website/docs/advanced/strategy-constraints.md @@ -5,6 +5,8 @@ title: Strategy Constraints :::info Availability Strategy constraints are available to Unleash Pro and Enterprise users. + +Unleash 4.9 introduced a more comprehensive set of constraint operators. These require that both Unleash *and* your client SDK of choice support them. See the [SDK compatibility table](../sdks/index.md#server-side-compatibility-table) for more information. ::: :::tip @@ -40,16 +42,16 @@ To clarify, here's a few example strategy constraints and what they do: ## Strategy constraint operators +:::note Placeholder context field +In this section, `` is used as a placeholder for an arbitrary context field. With the exception of the `currentTime` field, you can use any context field in its place. +::: + Unleash currently supports 15 different constraint operators. The operators can be grouped into four different categories based on their method of comparison. -Each operator forms a predicate together with the provided context field. +### Constraint negation / inversion -Each operator forms an expression of the form ` ` - -### Negation / inverse values - -All operators can be **negated**, meaning that they get their opposite value. Constraints are evaluated to either `true` or `false`. Negating an operator would turn a `true` into a `false` and a `false` value into a `true` value. +All operators can be **negated**, meaning that they get their opposite value. Constraints are evaluated to either `true` or `false`. Negating an operator would turn a `true` value into a `false` and a `false` value into a `true` value. For instance, using the numeric equivalence operator `NUM_EQ`, the following truth table shows the how value negation affects the result: @@ -61,8 +63,12 @@ For instance, using the numeric equivalence operator `NUM_EQ`, the following tru ### Numeric operators -| Name | `true` if `` is ... | -|-----------|-----------------------------------------------------------------------------| +Numeric operators compare the numeric values of context fields with your provided value. + +Numeric operators only accept single values. + +| Name | `true` if `` is ... | +|-----------|--------------------------------------------------------------------------------| | `NUM_EQ` | **equal** to the provided value; the mathematical `=` operator | | `NUM_GT` | **strictly greater than** the provided value; the mathematical `>` operator | | `NUM_GTE` | **greater than or equal to** the provided value; the mathematical `⩾` operator | @@ -73,16 +79,18 @@ You can read more about [numeric equality](https://en.wikipedia.org/wiki/Equalit ### Date and time operators -:::info Context field availability -The date and time operators are **only available on the `currentTime`** context field. +:::info `currentTime` and date and time operators +The date and time operators are **only available on the `currentTime`** context field. Furthermore, the `currentTime` context field **can not be used** with any of the other operators. ::: With the date and time operators, you can enable a feature before and/or after a specified time. -They compare the [Unleash context's](../user_guide/unleash_context) `currentTime` property. +The operators compare the [Unleash context's](../user_guide/unleash_context) `currentTime` property against the provided value. -You can combine the two constraint operators by setting two separate constraints on a single strategy to create a time span. +You can create a **time span** by combining the two constraint operators using two different constraints on the same strategy. In that case the strategy will be evaluated from `DATE_AFTER` and until `DATE_BEFORE`. +Date and time operators only support single values. + | Name | `true` if `currentTime` is ... | |---------------|--------------------------------| | `DATE_AFTER` | **after** the provided date | @@ -90,30 +98,35 @@ In that case the strategy will be evaluated from `DATE_AFTER` and until `DATE_BE ### String operators -String operators are all multi-value and most can be either case sensitive or insensitive - :::note Legacy note -For legacy reasons / backwards compatibility, `IN` and `NOT_IN` are always case sensitive. - -`IN` and `NOT_IN` are also each other's inverses. +For backwards compatibility reasons, `IN` and `NOT_IN` are always case-sensitive. ::: -In the below table, `` is used to indicate that the value of ... +String operators differ from the other categories in two different ways: +- all operators accept multiple values +- most operators also consider [letter case](https://en.wikipedia.org/wiki/Letter_case "letter case on Wikipedia") and can be set to be case-sensitive or case-insensitive -| Name | Available since | `true` if `` ... | -|-------------------|-----------------|------------------------------------------------| -| `IN` | 3.3 | is **equal** to any of the provided values | -| `NOT_IN` | 3.3 | is **not equal** to any of the provided values | -| `STR_CONTAINS` | 4.9 | **contains** any of the provided strings | -| `STR_ENDS_WITH` | 4.9 | **ends** with any of the provided strings | -| `STR_STARTS_WITH` | 4.9 | **starts** with any of the provided strings | +| Name | `true` if `` ... | Available since | +|-------------------|------------------------------------------------|-----------------| +| `IN` | is **equal** to any of the provided values | v3.3 | +| `NOT_IN` | is **not equal** to any of the provided values | v3.3 | +| `STR_CONTAINS` | **contains** any of the provided strings | v4.9 | +| `STR_ENDS_WITH` | **ends** with any of the provided strings | v4.9 | +| `STR_STARTS_WITH` | **starts** with any of the provided strings | v4.9 | -### Versioning (semver) operators +### Versioning (SemVer) operators + +The SemVer operators are used to compare version numbers such as application versions, dependency versions, etc. + +You can enter SemVer values with or without a leading "v": `v1.2.3` and `1.2.3` are both valid. +Importantly, they are also considered equal. Versions with pre-release indicators (e.g. `4.8.0-rc.2`) are considered less than versions without (e.g. `4.8.0`) in accordance with [the SemVer specification](https://semver.org/#spec-item-11). -| Name | `true` if `` is ... | +SemVer operators only support single values. + +| Name | `true` if `` is ... | |-------------|----------------------------------------------| | `SEMVER_EQ` | **equal** to the provided value | | `SEMVER_GT` | **strictly greater than** the provided value | From decdc083d07ff98fc835f1412dd6d6e98672e3be Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Tue, 8 Mar 2022 11:02:24 +0100 Subject: [PATCH 05/19] docs: finish first draft of new strat constraints doc. --- website/docs/advanced/strategy-constraints.md | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/website/docs/advanced/strategy-constraints.md b/website/docs/advanced/strategy-constraints.md index 73c6c33016..4d736db799 100644 --- a/website/docs/advanced/strategy-constraints.md +++ b/website/docs/advanced/strategy-constraints.md @@ -13,12 +13,33 @@ Unleash 4.9 introduced a more comprehensive set of constraint operators. These r This page explains what strategy constraints are in Unleash and how they work. If you want to know *how you add* strategy constraints to an activation strategy, see [the corresponding how-to guide](../how-to/how-to-add-strategy-constraints.md "how to add strategy constraints"). ::: -**Strategy constraints** allow you to set preconditions on activation strategies that must be satisfied for the activation strategy to take effect. For example, you might want a strategy to only trigger if a user belongs to a specific group or is in a specific country. - -Constraints use fields from the [Unleash Context](../user_guide/unleash_context) to determine whether a strategy should apply or not. You can constrain on both [standard context fields](../user_guide/unleash_context#structure) and on [custom context fields](../user_guide/unleash_context#custom-context-fields). A common use for using custom context fields is a multi-tenant service where you want to use a tenant identifier to control the feature rollout. This would allow you to decide which users should get access to your new feature based on the tenant. Other commonly seen custom context fields include fields for region, country, and customer type. +**Strategy constraints** are conditions that must be satisifed for an [activation strategy](../user_guide/activation_strategy) to be evaluated for a feature toggle. +With strategy constraints, you can: +- roll out a feature **only to users in a specific region** +- schedule a feature to be **released at a specific time** +- make a feature available for **a limited time only** +- release a feature to users with one of a set of **email addresses** +- ... and much more! -Combining strategy constraints with the [gradual rollout strategy](../user_guide/activation_strategy#gradual-rollout) allows you to do a gradual rollout to a specific segment of your user base. +Strategy constraints use fields from the [Unleash Context](../user_guide/unleash_context) to determine whether a strategy should apply or not. +You can constrain both on [standard context fields](../user_guide/unleash_context#structure) and on [custom context fields](../user_guide/unleash_context#custom-context-fields). + +## Constraining on custom context fields + +:::info Making custom context fields available +To be able to constrain on a field, it must be listed under the Context Field menu. If a field isn't listed, you can add it yourself. See [the how-to guide for creating your own custom fields](../how-to/how-to-define-custom-context-fields.md) for more info. +::: + +Unleash only provides a limited set of context fields by default, and they may not fulfill all your needs. +By using [custom context fields](../user_guide/unleash_context#custom-context-fields), you can tailor strategy constraints to your specific use case, such as: +- based on tenant IDs,release a feature to only specific tenants in a multi-tenant setup +- release a feature to users in a specific region +- release a feature only to beta testers + + + +You can also combine strategy constraints with the [gradual rollout strategy](../user_guide/activation_strategy#gradual-rollout) to do a gradual rollout to a **specific segment** of your user base. ![A toggle with the gradual rollout strategy. The toggle is constrained on the custom content field "region" and set to only activate if the region is Africa or Europe.](/img/custom-constraints.png) @@ -139,17 +160,12 @@ SemVer operators only support single values. This section gives a brief overview over to use the client SDKs to interact with strategy constraints. The exact steps will vary depending on which client you are using, so make sure to consult the documentation for your specific client SDK. ::: -Strategy constraints require [the Unleash Context](../user_guide/unleash_context) to work. All official [Unleash client SDKs](../sdks/index.md) support the option to pass [dynamic context values](../user_guide/unleash_context#structure "Unleash Context, section: structure") to the `isEnabled` function (or the SDKs equivalent). +Strategy constraints require [the Unleash Context](../user_guide/unleash_context) to work. All official [Unleash client SDKs](../sdks/index.md) support the option to pass [dynamic context values](../user_guide/unleash_context#structure "Unleash Context, section: structure") to the `isEnabled` function (or the SDK's equivalent). If the strategy constraint uses a [**standard Unleash Context field**](../user_guide/unleash_context#structure), set the context field to the value you wish to give it. If the strategy constraint uses a [**custom context field**](../user_guide/unleash_context#custom-context-fields), use the Unleash Context's `properties` field. Use the name of the custom context field as a key and set the value to your desired string. -## Prerequisites - -To be able to constrain on a field, it must be listed under the Context Field menu. If a field isn't listed, you can add it yourself. See [the how-to guide for creating your own custom fields](../how-to/how-to-define-custom-context-fields.md) for more info. - - ## [Deprecated]: Constrain on a specific environment {#constrain-on-a-specific-environment} Before Unleash 4.3, using strategy constraints was the recommended way to have different toggle configurations per environment. Now that Unleash has environment support built in, we no longer recommend you use strategy constraints for this. Instead, see the [environments documentation](../user_guide/environments). From 94f13075acfd37fb3aee298178033dc6622fe5d8 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Tue, 8 Mar 2022 11:14:55 +0100 Subject: [PATCH 06/19] docs: add unleash context and compat table updates --- website/docs/sdks/index.md | 101 +++++++++++---------- website/docs/user_guide/unleash-context.md | 19 ++-- 2 files changed, 62 insertions(+), 58 deletions(-) diff --git a/website/docs/sdks/index.md b/website/docs/sdks/index.md index dd04111233..4e849f623a 100644 --- a/website/docs/sdks/index.md +++ b/website/docs/sdks/index.md @@ -50,56 +50,57 @@ If you see an item marked with a ❌ that you would find useful, feel free to re | Capability | [Java](/sdks/java_sdk) | [Node.js](/sdks/node_sdk) | [Go](/sdks/go_sdk) | [Python](/sdks/python_sdk) | [Ruby](/sdks/ruby_sdk) | [.NET](/sdks/dot_net_sdk) | [PHP](/sdks/php_sdk) | [Rust](https://github.com/unleash/unleash-client-rust) | [Unleash Proxy](unleash-proxy.md) | -|---------------------------------------------------------------------------------------------------|:----------------------:|:-------------------------:|:------------------:|:--------------------------:|:----------------------:|:-------------------------:|:--------------------:|:------------------------------------------------------:|:----------------------------------------:| -| **Category: Initialization** | | | | | | | | | | -| Async initialization | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | N/A | -| Can block until synchronized | ✅ | ✅ | ✅ | ⭕ | ⭕ | ✅ | ⭕ | ⭕ | N/A | -| Default refresh interval | 10s | 15s | 15s | 15s | 15s | 30s | 30s | 15s | 5s | -| Default metrics interval | 60s | 60s | 60s | 60s | 60s | 60s | 30s | 15s | 30s | -| Context provider | ✅ | N/A | N/A | N/A | N/A | ✅ | ✅ | N/A | N/A | -| Global fallback function | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | N/A | -| Toggle Query: `namePrefix` | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| Toggle Query: `tags` | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| Toggle Query: `project_name` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | N/A | ⭕ | | -| **Category: Custom Headers** | | | | | | | | | | -| static | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | N/A | -| function | ✅ | ✅ | ⭕ | ✅ | ⭕ | ✅ | ⭕ | ⭕ | N/A | -| **Category: Built-in strategies** | | | | | | | | | | -| [Standard](../user_guide/activation_strategy#standard) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| [Gradual rollout](../user_guide/activation_strategy#gradual-rollout) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| [Gradual rollout: custom stickiness](../user_guide/activation_strategy#customize-stickiness-beta) | ✅ | ✅ | ⭕ | ✅ | ✅ | ✅ | ✅ | ⭕ | | -| [UserID](../user_guide/activation_strategy#userids) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| [IP](../user_guide/activation_strategy#ips) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| [IP](../user_guide/activation_strategy#ips): CIDR syntax | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | ⭕ | ✅ | | -| [Hostname](../user_guide/activation_strategy#hostnames) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| **Category: [Custom strategies](../advanced/custom_activation_strategy)** | | | | | | | | | | -| Basic support | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| **Category: [Strategy constraints](../advanced/strategy_constraints)** | | | | | | | | | | -| Basic support (`IN`, `NOT_IN` operators) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| Advanced support (Semver, date, numeric and extended string operators) | ✅ | ✅ | ⭕ | ⭕ | ⭕ | ⭕ | ✅ | ⭕ | | -| **Category: [Unleash Context](../user_guide/unleash_context)** | | | | | | | | | | -| Static fields (`environment`, `appName`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| Defined fields | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| Custom properties | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| **Category: [`isEnabled`](../client-specification#implementation-of-isenabled)** | | | | | | | | | | -| Can take context | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| Override fallback value | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| Fallback function | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | ⭕ | ⭕ | | -| **Category: [Variants](../advanced/toggle_variants)** | | | | | | | | | | -| Basic support | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| Custom fallback variant | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | | -| Custom weight | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | | -| [Custom stickiness (beta)](../advanced/stickiness#custom-stickiness-beta) | ✅ | ✅ | ⭕ | ✅ | ✅ | ✅ | ✅ | ⭕ | | -| **Category: Local backup** | | | | | | | | | | -| File based backup | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | | -| **Category: Usage metrics** | | | | | | | | | | -| Can disable metrics | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| Client registration | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| Basic usage metrics (yes/no) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| [Impression data](../advanced/impression-data.md) | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ | N/A | -| **Category: Bootstrap (beta)** | | | | | | | | | | -| Bootstrap from file | ✅ | ✅ | ⭕ | ⭕ | ✅ | ⭕ | ⭕ | ⭕ | ✅ | -| Custom Bootstrap implementation | ✅ | ✅ | ⭕ | ⭕ | ✅ | ⭕ | ⭕ | ⭕ | ✅ | +|---------------------------------------------------------------------------------------------------|:----------------------:|:-------------------------:|:------------------:|:--------------------------:|:----------------------:|:-------------------------:|:--------------------:|:------------------------------------------------------:|:---------------------------------:| +| **Category: Initialization** | | | | | | | | | | +| Async initialization | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | N/A | +| Can block until synchronized | ✅ | ✅ | ✅ | ⭕ | ⭕ | ✅ | ⭕ | ⭕ | N/A | +| Default refresh interval | 10s | 15s | 15s | 15s | 15s | 30s | 30s | 15s | 5s | +| Default metrics interval | 60s | 60s | 60s | 60s | 60s | 60s | 30s | 15s | 30s | +| Context provider | ✅ | N/A | N/A | N/A | N/A | ✅ | ✅ | N/A | N/A | +| Global fallback function | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | N/A | +| Toggle Query: `namePrefix` | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| Toggle Query: `tags` | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| Toggle Query: `project_name` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | N/A | ⭕ | | +| **Category: Custom Headers** | | | | | | | | | | +| static | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | N/A | +| function | ✅ | ✅ | ⭕ | ✅ | ⭕ | ✅ | ⭕ | ⭕ | N/A | +| **Category: Built-in strategies** | | | | | | | | | | +| [Standard](../user_guide/activation_strategy#standard) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| [Gradual rollout](../user_guide/activation_strategy#gradual-rollout) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| [Gradual rollout: custom stickiness](../user_guide/activation_strategy#customize-stickiness-beta) | ✅ | ✅ | ⭕ | ✅ | ✅ | ✅ | ✅ | ⭕ | | +| [UserID](../user_guide/activation_strategy#userids) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| [IP](../user_guide/activation_strategy#ips) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| [IP](../user_guide/activation_strategy#ips): CIDR syntax | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | ⭕ | ✅ | | +| [Hostname](../user_guide/activation_strategy#hostnames) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| **Category: [Custom strategies](../advanced/custom_activation_strategy)** | | | | | | | | | | +| Basic support | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| **Category: [Strategy constraints](../advanced/strategy_constraints)** | | | | | | | | | | +| Basic support (`IN`, `NOT_IN` operators) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| Advanced support (Semver, date, numeric and extended string operators) | ✅ | ✅ | ⭕ | ⭕ | ⭕ | ⭕ | ✅ | ⭕ | | +| **Category: [Unleash Context](../user_guide/unleash_context)** | | | | | | | | | | +| Static fields (`environment`, `appName`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| Defined fields | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| Custom properties | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +|`currentTime` context field | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| **Category: [`isEnabled`](../client-specification#implementation-of-isenabled)** | | | | | | | | | | +| Can take context | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| Override fallback value | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| Fallback function | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | ⭕ | ⭕ | | +| **Category: [Variants](../advanced/toggle_variants)** | | | | | | | | | | +| Basic support | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| Custom fallback variant | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | | +| Custom weight | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | | +| [Custom stickiness (beta)](../advanced/stickiness#custom-stickiness-beta) | ✅ | ✅ | ⭕ | ✅ | ✅ | ✅ | ✅ | ⭕ | | +| **Category: Local backup** | | | | | | | | | | +| File based backup | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | | +| **Category: Usage metrics** | | | | | | | | | | +| Can disable metrics | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| Client registration | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| Basic usage metrics (yes/no) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| [Impression data](../advanced/impression-data.md) | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ | N/A | +| **Category: Bootstrap (beta)** | | | | | | | | | | +| Bootstrap from file | ✅ | ✅ | ⭕ | ⭕ | ✅ | ⭕ | ⭕ | ⭕ | ✅ | +| Custom Bootstrap implementation | ✅ | ✅ | ⭕ | ⭕ | ✅ | ⭕ | ⭕ | ⭕ | ✅ | ## Community SDKs ❤️ {#community-sdks} diff --git a/website/docs/user_guide/unleash-context.md b/website/docs/user_guide/unleash-context.md index df613092dd..60709009d5 100644 --- a/website/docs/user_guide/unleash-context.md +++ b/website/docs/user_guide/unleash-context.md @@ -17,14 +17,15 @@ _All fields are optional_, but some strategies depend on certain fields being pr The below table gives a brief overview over what the fields' intended usage is, their lifetime, and their type. Note that the exact type can vary between programming languages and implementations. Be sure to consult your specific client SDK for more information on its implementation of the Unleash Context. -| field name | type | lifetime | description | -|-------------------|-----------------------|----------|----------------------------------------| -| `appName` | `string` | static | the name of the application | -| `environment`[^1] | `string` | static | the environment the app is running in | -| `userId` | `string` | dynamic | an identifier for the current user | -| `sessionId` | `string` | dynamic | an identifier for the current session | -| `remoteAddress` | `string` | dynamic | an identifier for the current session | -| `properties` | `Map` | dynamic | a key-value store of any data you want | +| field name | type | lifetime | description | introduced in | +|-------------------|-----------------------|----------|--------------------------------------------------------------------------------------------|---------------| +| `appName` | `string` | static | the name of the application | | +| `environment`[^1] | `string` | static | the environment the app is running in | | +| `userId` | `string` | dynamic | an identifier for the current user | | +| `sessionId` | `string` | dynamic | an identifier for the current session | | +| `remoteAddress` | `string` | dynamic | an identifier for the current session | | +| `properties` | `Map` | dynamic | a key-value store of any data you want | | +| `currentTime`[^2] | `DateTime`/`string` | special / read-only | A `DateTime` (or similar) data class instance or a string in an RFC3339-compatible format. | v4.9 | ### The `properties` field @@ -76,3 +77,5 @@ Any context field _can_ be used to [calculate custom stickiness](../advanced/sti [^1]: If you're on Unleash 4.3 or higher, you'll probably want to use [the environments feature](../user_guide/environments.md) instead of relying on the `environment` context field when working with environments. + +[^2]: Check the [compatibility table](../sdks/index.md#current-time-server) for an overview of which SDKs provide the `currentTime` property. From 05187ce6a9e8adc2964beaf2d71222f3397592bb Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Tue, 8 Mar 2022 11:20:06 +0100 Subject: [PATCH 07/19] fix: remove placeholder comment --- website/docs/advanced/strategy-constraints.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/website/docs/advanced/strategy-constraints.md b/website/docs/advanced/strategy-constraints.md index 4d736db799..a39e3a48b8 100644 --- a/website/docs/advanced/strategy-constraints.md +++ b/website/docs/advanced/strategy-constraints.md @@ -37,8 +37,6 @@ By using [custom context fields](../user_guide/unleash_context#custom-context-fi - release a feature to users in a specific region - release a feature only to beta testers - - You can also combine strategy constraints with the [gradual rollout strategy](../user_guide/activation_strategy#gradual-rollout) to do a gradual rollout to a **specific segment** of your user base. ![A toggle with the gradual rollout strategy. The toggle is constrained on the custom content field "region" and set to only activate if the region is Africa or Europe.](/img/custom-constraints.png) From 4ce4a9c2d6d0eac80df5d06c7cd849ed17420a2e Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Tue, 8 Mar 2022 11:22:24 +0100 Subject: [PATCH 08/19] docs: remove 'introduced in' column in Unleash Context table. --- website/docs/user_guide/unleash-context.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/website/docs/user_guide/unleash-context.md b/website/docs/user_guide/unleash-context.md index 60709009d5..87319ed03b 100644 --- a/website/docs/user_guide/unleash-context.md +++ b/website/docs/user_guide/unleash-context.md @@ -17,15 +17,15 @@ _All fields are optional_, but some strategies depend on certain fields being pr The below table gives a brief overview over what the fields' intended usage is, their lifetime, and their type. Note that the exact type can vary between programming languages and implementations. Be sure to consult your specific client SDK for more information on its implementation of the Unleash Context. -| field name | type | lifetime | description | introduced in | -|-------------------|-----------------------|----------|--------------------------------------------------------------------------------------------|---------------| -| `appName` | `string` | static | the name of the application | | -| `environment`[^1] | `string` | static | the environment the app is running in | | -| `userId` | `string` | dynamic | an identifier for the current user | | -| `sessionId` | `string` | dynamic | an identifier for the current session | | -| `remoteAddress` | `string` | dynamic | an identifier for the current session | | -| `properties` | `Map` | dynamic | a key-value store of any data you want | | -| `currentTime`[^2] | `DateTime`/`string` | special / read-only | A `DateTime` (or similar) data class instance or a string in an RFC3339-compatible format. | v4.9 | +| field name | type | lifetime | description | +|-------------------|-----------------------|---------------------|--------------------------------------------------------------------------------------------| +| `appName` | `string` | static | the name of the application | +| `environment`[^1] | `string` | static | the environment the app is running in | +| `userId` | `string` | dynamic | an identifier for the current user | +| `sessionId` | `string` | dynamic | an identifier for the current session | +| `remoteAddress` | `string` | dynamic | an identifier for the current session | +| `properties` | `Map` | dynamic | a key-value store of any data you want | +| `currentTime`[^2] | `DateTime`/`string` | special / read-only | A `DateTime` (or similar) data class instance or a string in an RFC3339-compatible format. | ### The `properties` field From 774bed5bee675c635dff7e89d550a10c1e26b3ee Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Tue, 8 Mar 2022 12:53:56 +0100 Subject: [PATCH 09/19] fix: mark .NET sdk as not having `currentTime` context field --- website/docs/sdks/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/sdks/index.md b/website/docs/sdks/index.md index 4e849f623a..1e3230bad8 100644 --- a/website/docs/sdks/index.md +++ b/website/docs/sdks/index.md @@ -81,7 +81,7 @@ If you see an item marked with a ❌ that you would find useful, feel free to re | Static fields (`environment`, `appName`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | Defined fields | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | Custom properties | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -|`currentTime` context field | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| `currentTime` context field | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | ✅ | ✅ | | | **Category: [`isEnabled`](../client-specification#implementation-of-isenabled)** | | | | | | | | | | | Can take context | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | Override fallback value | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | From 39d01f46eccf108e00c4f04127cc2d27796cb42d Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Tue, 8 Mar 2022 12:57:09 +0100 Subject: [PATCH 10/19] docs: move string operator case sensitivity note to table --- website/docs/advanced/strategy-constraints.md | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/website/docs/advanced/strategy-constraints.md b/website/docs/advanced/strategy-constraints.md index a39e3a48b8..ba20969cc8 100644 --- a/website/docs/advanced/strategy-constraints.md +++ b/website/docs/advanced/strategy-constraints.md @@ -117,21 +117,17 @@ Date and time operators only support single values. ### String operators -:::note Legacy note -For backwards compatibility reasons, `IN` and `NOT_IN` are always case-sensitive. -::: - String operators differ from the other categories in two different ways: - all operators accept multiple values - most operators also consider [letter case](https://en.wikipedia.org/wiki/Letter_case "letter case on Wikipedia") and can be set to be case-sensitive or case-insensitive -| Name | `true` if `` ... | Available since | -|-------------------|------------------------------------------------|-----------------| -| `IN` | is **equal** to any of the provided values | v3.3 | -| `NOT_IN` | is **not equal** to any of the provided values | v3.3 | -| `STR_CONTAINS` | **contains** any of the provided strings | v4.9 | -| `STR_ENDS_WITH` | **ends** with any of the provided strings | v4.9 | -| `STR_STARTS_WITH` | **starts** with any of the provided strings | v4.9 | +| Name | `true` if `` ... | Supports case-insensitivity | Available since | +|-------------------|------------------------------------------------|-----------------------------|-----------------| +| `IN` | is **equal** to any of the provided values | No | v3.3 | +| `NOT_IN` | is **not equal** to any of the provided values | No | v3.3 | +| `STR_CONTAINS` | **contains** any of the provided strings | Yes | v4.9 | +| `STR_ENDS_WITH` | **ends** with any of the provided strings | Yes | v4.9 | +| `STR_STARTS_WITH` | **starts** with any of the provided strings | Yes | v4.9 | ### Versioning (SemVer) operators From 2f6b067eb54b0c6660d7078c7f22ab02bb4db017 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Tue, 8 Mar 2022 13:27:19 +0100 Subject: [PATCH 11/19] docs: Update SemVer section: clarify what requirements we have --- website/docs/advanced/strategy-constraints.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/website/docs/advanced/strategy-constraints.md b/website/docs/advanced/strategy-constraints.md index ba20969cc8..cd6e7815d4 100644 --- a/website/docs/advanced/strategy-constraints.md +++ b/website/docs/advanced/strategy-constraints.md @@ -134,20 +134,25 @@ String operators differ from the other categories in two different ways: The SemVer operators are used to compare version numbers such as application versions, dependency versions, etc. +The SemVer input must follow a few rules: +- The value you enter must at least consist of three version numbers separated by full stops. Example: `1.2.3` +- Optionally, you can also add pre-release version information by adding a hyphen and series of dot separated identifiers after the patch version. Example: `1.2.3-rc.2` + You can enter SemVer values with or without a leading "v": `v1.2.3` and `1.2.3` are both valid. Importantly, they are also considered equal. -Versions with pre-release indicators (e.g. `4.8.0-rc.2`) are considered less than versions without (e.g. `4.8.0`) in accordance with [the SemVer specification](https://semver.org/#spec-item-11). +Versions with pre-release indicators (e.g. `4.8.0-rc.2`) are considered *less than* versions without (e.g. `4.8.0`) in accordance with [the SemVer specification, item 11](https://semver.org/#spec-item-11). + +You can read more about SemVer in [the full SemVer specification](https://semver.org/). SemVer operators only support single values. -| Name | `true` if `` is ... | +| Name | `true` if `` is ... | |-------------|----------------------------------------------| | `SEMVER_EQ` | **equal** to the provided value | | `SEMVER_GT` | **strictly greater than** the provided value | | `SEMVER_LT` | **strictly less than** the provided value | - ## Interacting with strategy constraints in the client SDKs {#sdks} :::note From 419dda09a09d960f22c042866df4793c81a2cdd8 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Tue, 8 Mar 2022 13:31:55 +0100 Subject: [PATCH 12/19] docs: Update description of `currentTime` in the Unleash context. --- website/docs/user_guide/unleash-context.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/website/docs/user_guide/unleash-context.md b/website/docs/user_guide/unleash-context.md index 87319ed03b..14c752aaef 100644 --- a/website/docs/user_guide/unleash-context.md +++ b/website/docs/user_guide/unleash-context.md @@ -17,15 +17,16 @@ _All fields are optional_, but some strategies depend on certain fields being pr The below table gives a brief overview over what the fields' intended usage is, their lifetime, and their type. Note that the exact type can vary between programming languages and implementations. Be sure to consult your specific client SDK for more information on its implementation of the Unleash Context. -| field name | type | lifetime | description | -|-------------------|-----------------------|---------------------|--------------------------------------------------------------------------------------------| -| `appName` | `string` | static | the name of the application | -| `environment`[^1] | `string` | static | the environment the app is running in | -| `userId` | `string` | dynamic | an identifier for the current user | -| `sessionId` | `string` | dynamic | an identifier for the current session | -| `remoteAddress` | `string` | dynamic | an identifier for the current session | -| `properties` | `Map` | dynamic | a key-value store of any data you want | -| `currentTime`[^2] | `DateTime`/`string` | special / read-only | A `DateTime` (or similar) data class instance or a string in an RFC3339-compatible format. | +| field name | type | lifetime | description | +|-------------------|-----------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------| +| `appName` | `string` | static | the name of the application | +| `environment`[^1] | `string` | static | the environment the app is running in | +| `userId` | `string` | dynamic | an identifier for the current user | +| `sessionId` | `string` | dynamic | an identifier for the current session | +| `remoteAddress` | `string` | dynamic | an identifier for the current session | +| `properties` | `Map` | dynamic | a key-value store of any data you want | +| `currentTime`[^2] | `DateTime`/`string` | dynamic | A `DateTime` (or similar) data class instance or a string in an RFC3339-compatible format. **Defaults to the current time** if not set by the user. | +| | | | | ### The `properties` field From c0eac49313b5bbb8395986aae411bcb7095f3ca8 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Tue, 8 Mar 2022 13:34:11 +0100 Subject: [PATCH 13/19] fix: delete empty table row --- website/docs/user_guide/unleash-context.md | 1 - 1 file changed, 1 deletion(-) diff --git a/website/docs/user_guide/unleash-context.md b/website/docs/user_guide/unleash-context.md index 14c752aaef..1020c1235a 100644 --- a/website/docs/user_guide/unleash-context.md +++ b/website/docs/user_guide/unleash-context.md @@ -26,7 +26,6 @@ The below table gives a brief overview over what the fields' intended usage is, | `remoteAddress` | `string` | dynamic | an identifier for the current session | | `properties` | `Map` | dynamic | a key-value store of any data you want | | `currentTime`[^2] | `DateTime`/`string` | dynamic | A `DateTime` (or similar) data class instance or a string in an RFC3339-compatible format. **Defaults to the current time** if not set by the user. | -| | | | | ### The `properties` field From fee4caf2f9adc7f5f9bb1b79c512d22c1f45cd0d Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Tue, 8 Mar 2022 13:44:02 +0100 Subject: [PATCH 14/19] docs: Add note about how invalid context field values are handled --- website/docs/advanced/strategy-constraints.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/website/docs/advanced/strategy-constraints.md b/website/docs/advanced/strategy-constraints.md index cd6e7815d4..0311783f60 100644 --- a/website/docs/advanced/strategy-constraints.md +++ b/website/docs/advanced/strategy-constraints.md @@ -68,9 +68,9 @@ In this section, `` is used as a placeholder for an arbitrary con Unleash currently supports 15 different constraint operators. The operators can be grouped into four different categories based on their method of comparison. -### Constraint negation / inversion +### Constraint negation / inversion {#constraint-negation} -All operators can be **negated**, meaning that they get their opposite value. Constraints are evaluated to either `true` or `false`. Negating an operator would turn a `true` value into a `false` and a `false` value into a `true` value. +All constraint expressions can be **negated**, meaning that they get their opposite value. Constraints are evaluated to either `true` or `false`. Negating a constraint would turn a `true` value into a `false` and a `false` value into a `true` value. For instance, using the numeric equivalence operator `NUM_EQ`, the following truth table shows the how value negation affects the result: @@ -165,6 +165,12 @@ If the strategy constraint uses a [**standard Unleash Context field**](../user_g If the strategy constraint uses a [**custom context field**](../user_guide/unleash_context#custom-context-fields), use the Unleash Context's `properties` field. Use the name of the custom context field as a key and set the value to your desired string. +If you set a context field to a value that the SDKs cannot parse correctly for a chosen constraint operator, the strategy constraint will evaluate to false. +In other words: if you have a strategy constraint operator that expects a number, such as `NUM_GT`, but you set the corresponding context field to a string value, then the expression will be false: `"some string"` is **not** greater than `5`. +This value can still be negated as explained in [the section on negating values](#constraint-negation). + + + ## [Deprecated]: Constrain on a specific environment {#constrain-on-a-specific-environment} Before Unleash 4.3, using strategy constraints was the recommended way to have different toggle configurations per environment. Now that Unleash has environment support built in, we no longer recommend you use strategy constraints for this. Instead, see the [environments documentation](../user_guide/environments). From db9a0e2c543dc5ef0521306ad14ec767c59d685f Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Tue, 8 Mar 2022 13:58:16 +0100 Subject: [PATCH 15/19] chore: merge main -> this branch --- package.json | 4 +- website/docs/sdks/index.md | 100 ++++++++++++++++++------------------- yarn.lock | 94 +++++++++++++++++----------------- 3 files changed, 99 insertions(+), 99 deletions(-) diff --git a/package.json b/package.json index fe6c19f24e..059132fea1 100644 --- a/package.json +++ b/package.json @@ -134,8 +134,8 @@ "@types/supertest": "2.0.11", "@types/type-is": "1.6.3", "@types/uuid": "8.3.4", - "@typescript-eslint/eslint-plugin": "5.13.0", - "@typescript-eslint/parser": "5.13.0", + "@typescript-eslint/eslint-plugin": "5.14.0", + "@typescript-eslint/parser": "5.14.0", "copyfiles": "2.4.1", "coveralls": "3.1.1", "del-cli": "4.0.1", diff --git a/website/docs/sdks/index.md b/website/docs/sdks/index.md index 1e3230bad8..cb27b17189 100644 --- a/website/docs/sdks/index.md +++ b/website/docs/sdks/index.md @@ -50,57 +50,57 @@ If you see an item marked with a ❌ that you would find useful, feel free to re | Capability | [Java](/sdks/java_sdk) | [Node.js](/sdks/node_sdk) | [Go](/sdks/go_sdk) | [Python](/sdks/python_sdk) | [Ruby](/sdks/ruby_sdk) | [.NET](/sdks/dot_net_sdk) | [PHP](/sdks/php_sdk) | [Rust](https://github.com/unleash/unleash-client-rust) | [Unleash Proxy](unleash-proxy.md) | -|---------------------------------------------------------------------------------------------------|:----------------------:|:-------------------------:|:------------------:|:--------------------------:|:----------------------:|:-------------------------:|:--------------------:|:------------------------------------------------------:|:---------------------------------:| -| **Category: Initialization** | | | | | | | | | | -| Async initialization | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | N/A | -| Can block until synchronized | ✅ | ✅ | ✅ | ⭕ | ⭕ | ✅ | ⭕ | ⭕ | N/A | -| Default refresh interval | 10s | 15s | 15s | 15s | 15s | 30s | 30s | 15s | 5s | -| Default metrics interval | 60s | 60s | 60s | 60s | 60s | 60s | 30s | 15s | 30s | -| Context provider | ✅ | N/A | N/A | N/A | N/A | ✅ | ✅ | N/A | N/A | -| Global fallback function | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | N/A | -| Toggle Query: `namePrefix` | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| Toggle Query: `tags` | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | -| Toggle Query: `project_name` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | N/A | ⭕ | | -| **Category: Custom Headers** | | | | | | | | | | -| static | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | N/A | -| function | ✅ | ✅ | ⭕ | ✅ | ⭕ | ✅ | ⭕ | ⭕ | N/A | -| **Category: Built-in strategies** | | | | | | | | | | -| [Standard](../user_guide/activation_strategy#standard) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| [Gradual rollout](../user_guide/activation_strategy#gradual-rollout) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| [Gradual rollout: custom stickiness](../user_guide/activation_strategy#customize-stickiness-beta) | ✅ | ✅ | ⭕ | ✅ | ✅ | ✅ | ✅ | ⭕ | | -| [UserID](../user_guide/activation_strategy#userids) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| [IP](../user_guide/activation_strategy#ips) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| [IP](../user_guide/activation_strategy#ips): CIDR syntax | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | ⭕ | ✅ | | -| [Hostname](../user_guide/activation_strategy#hostnames) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| **Category: [Custom strategies](../advanced/custom_activation_strategy)** | | | | | | | | | | -| Basic support | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| **Category: [Strategy constraints](../advanced/strategy_constraints)** | | | | | | | | | | -| Basic support (`IN`, `NOT_IN` operators) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| Advanced support (Semver, date, numeric and extended string operators) | ✅ | ✅ | ⭕ | ⭕ | ⭕ | ⭕ | ✅ | ⭕ | | -| **Category: [Unleash Context](../user_guide/unleash_context)** | | | | | | | | | | -| Static fields (`environment`, `appName`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| Defined fields | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| Custom properties | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +|---------------------------------------------------------------------------------------------------|:----------------------:|:-------------------------:|:------------------:|:--------------------------:|:----------------------:|:-------------------------:|:--------------------:|:------------------------------------------------------:|:----------------------------------------:| +| **Category: Initialization** | | | | | | | | | | +| Async initialization | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | N/A | +| Can block until synchronized | ✅ | ✅ | ✅ | ⭕ | ⭕ | ✅ | ✅ | ⭕ | N/A | +| Default refresh interval | 10s | 15s | 15s | 15s | 15s | 30s | 30s | 15s | 5s | +| Default metrics interval | 60s | 60s | 60s | 60s | 60s | 60s | 30s | 15s | 30s | +| Context provider | ✅ | N/A | N/A | N/A | N/A | ✅ | ✅ | N/A | N/A | +| Global fallback function | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | N/A | +| Toggle Query: `namePrefix` | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| Toggle Query: `tags` | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | +| Toggle Query: `project_name` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | N/A | ⭕ | | +| **Category: Custom Headers** | | | | | | | | | | +| static | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | N/A | +| function | ✅ | ✅ | ⭕ | ✅ | ⭕ | ✅ | ✅ | ⭕ | N/A | +| **Category: Built-in strategies** | | | | | | | | | | +| [Standard](../user_guide/activation_strategy#standard) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| [Gradual rollout](../user_guide/activation_strategy#gradual-rollout) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| [Gradual rollout: custom stickiness](../user_guide/activation_strategy#customize-stickiness-beta) | ✅ | ✅ | ⭕ | ✅ | ✅ | ✅ | ✅ | ⭕ | | +| [UserID](../user_guide/activation_strategy#userids) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| [IP](../user_guide/activation_strategy#ips) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| [IP](../user_guide/activation_strategy#ips): CIDR syntax | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | ⭕ | ✅ | | +| [Hostname](../user_guide/activation_strategy#hostnames) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| **Category: [Custom strategies](../advanced/custom_activation_strategy)** | | | | | | | | | | +| Basic support | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| **Category: [Strategy constraints](../advanced/strategy_constraints)** | | | | | | | | | | +| Basic support (`IN`, `NOT_IN` operators) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| Advanced support (Semver, date, numeric and extended string operators) | ✅ | ✅ | ⭕ | ⭕ | ⭕ | ⭕ | ✅ | ⭕ | | +| **Category: [Unleash Context](../user_guide/unleash_context)** | | | | | | | | | | +| Static fields (`environment`, `appName`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| Defined fields | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| Custom properties | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | `currentTime` context field | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | ✅ | ✅ | | -| **Category: [`isEnabled`](../client-specification#implementation-of-isenabled)** | | | | | | | | | | -| Can take context | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| Override fallback value | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| Fallback function | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | ⭕ | ⭕ | | -| **Category: [Variants](../advanced/toggle_variants)** | | | | | | | | | | -| Basic support | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| Custom fallback variant | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | | -| Custom weight | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | | -| [Custom stickiness (beta)](../advanced/stickiness#custom-stickiness-beta) | ✅ | ✅ | ⭕ | ✅ | ✅ | ✅ | ✅ | ⭕ | | -| **Category: Local backup** | | | | | | | | | | -| File based backup | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | | -| **Category: Usage metrics** | | | | | | | | | | -| Can disable metrics | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| Client registration | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| Basic usage metrics (yes/no) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| [Impression data](../advanced/impression-data.md) | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ | N/A | -| **Category: Bootstrap (beta)** | | | | | | | | | | -| Bootstrap from file | ✅ | ✅ | ⭕ | ⭕ | ✅ | ⭕ | ⭕ | ⭕ | ✅ | -| Custom Bootstrap implementation | ✅ | ✅ | ⭕ | ⭕ | ✅ | ⭕ | ⭕ | ⭕ | ✅ | +| **Category: [`isEnabled`](../client-specification#implementation-of-isenabled)** | | | | | | | | | | +| Can take context | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| Override fallback value | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| Fallback function | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | ⭕ | ⭕ | | +| **Category: [Variants](../advanced/toggle_variants)** | | | | | | | | | | +| Basic support | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| Custom fallback variant | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | | +| Custom weight | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | | +| [Custom stickiness (beta)](../advanced/stickiness#custom-stickiness-beta) | ✅ | ✅ | ⭕ | ✅ | ✅ | ✅ | ✅ | ⭕ | | +| **Category: Local backup** | | | | | | | | | | +| File based backup | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | | +| **Category: Usage metrics** | | | | | | | | | | +| Can disable metrics | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| Client registration | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| Basic usage metrics (yes/no) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | +| [Impression data](../advanced/impression-data.md) | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ | N/A | +| **Category: Bootstrap (beta)** | | | | | | | | | | +| Bootstrap from file | ✅ | ✅ | ⭕ | ⭕ | ✅ | ⭕ | ✅ | ⭕ | ✅ | +| Custom Bootstrap implementation | ✅ | ✅ | ⭕ | ⭕ | ✅ | ⭕ | ✅ | ⭕ | ✅ | ## Community SDKs ❤️ {#community-sdks} diff --git a/yarn.lock b/yarn.lock index e6920e3e97..aa7774d0f9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1215,14 +1215,14 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@5.13.0": - version "5.13.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.13.0.tgz#2809052b85911ced9c54a60dac10e515e9114497" - integrity sha512-vLktb2Uec81fxm/cfz2Hd6QaWOs8qdmVAZXLdOBX6JFJDhf6oDZpMzZ4/LZ6SFM/5DgDcxIMIvy3F+O9yZBuiQ== +"@typescript-eslint/eslint-plugin@5.14.0": + version "5.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.14.0.tgz#5119b67152356231a0e24b998035288a9cd21335" + integrity sha512-ir0wYI4FfFUDfLcuwKzIH7sMVA+db7WYen47iRSaCGl+HMAZI9fpBwfDo45ZALD3A45ZGyHWDNLhbg8tZrMX4w== dependencies: - "@typescript-eslint/scope-manager" "5.13.0" - "@typescript-eslint/type-utils" "5.13.0" - "@typescript-eslint/utils" "5.13.0" + "@typescript-eslint/scope-manager" "5.14.0" + "@typescript-eslint/type-utils" "5.14.0" + "@typescript-eslint/utils" "5.14.0" debug "^4.3.2" functional-red-black-tree "^1.0.1" ignore "^5.1.8" @@ -1230,69 +1230,69 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/parser@5.13.0": - version "5.13.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.13.0.tgz#0394ed8f2f849273c0bf4b811994d177112ced5c" - integrity sha512-GdrU4GvBE29tm2RqWOM0P5QfCtgCyN4hXICj/X9ibKED16136l9ZpoJvCL5pSKtmJzA+NRDzQ312wWMejCVVfg== +"@typescript-eslint/parser@5.14.0": + version "5.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.14.0.tgz#7c79f898aa3cff0ceee6f1d34eeed0f034fb9ef3" + integrity sha512-aHJN8/FuIy1Zvqk4U/gcO/fxeMKyoSv/rS46UXMXOJKVsLQ+iYPuXNbpbH7cBLcpSbmyyFbwrniLx5+kutu1pw== dependencies: - "@typescript-eslint/scope-manager" "5.13.0" - "@typescript-eslint/types" "5.13.0" - "@typescript-eslint/typescript-estree" "5.13.0" + "@typescript-eslint/scope-manager" "5.14.0" + "@typescript-eslint/types" "5.14.0" + "@typescript-eslint/typescript-estree" "5.14.0" debug "^4.3.2" -"@typescript-eslint/scope-manager@5.13.0": - version "5.13.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.13.0.tgz#cf6aff61ca497cb19f0397eea8444a58f46156b6" - integrity sha512-T4N8UvKYDSfVYdmJq7g2IPJYCRzwtp74KyDZytkR4OL3NRupvswvmJQJ4CX5tDSurW2cvCc1Ia1qM7d0jpa7IA== +"@typescript-eslint/scope-manager@5.14.0": + version "5.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.14.0.tgz#ea518962b42db8ed0a55152ea959c218cb53ca7b" + integrity sha512-LazdcMlGnv+xUc5R4qIlqH0OWARyl2kaP8pVCS39qSL3Pd1F7mI10DbdXeARcE62sVQE4fHNvEqMWsypWO+yEw== dependencies: - "@typescript-eslint/types" "5.13.0" - "@typescript-eslint/visitor-keys" "5.13.0" + "@typescript-eslint/types" "5.14.0" + "@typescript-eslint/visitor-keys" "5.14.0" -"@typescript-eslint/type-utils@5.13.0": - version "5.13.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.13.0.tgz#b0efd45c85b7bab1125c97b752cab3a86c7b615d" - integrity sha512-/nz7qFizaBM1SuqAKb7GLkcNn2buRdDgZraXlkhz+vUGiN1NZ9LzkA595tHHeduAiS2MsHqMNhE2zNzGdw43Yg== +"@typescript-eslint/type-utils@5.14.0": + version "5.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.14.0.tgz#711f08105860b12988454e91df433567205a8f0b" + integrity sha512-d4PTJxsqaUpv8iERTDSQBKUCV7Q5yyXjqXUl3XF7Sd9ogNLuKLkxz82qxokqQ4jXdTPZudWpmNtr/JjbbvUixw== dependencies: - "@typescript-eslint/utils" "5.13.0" + "@typescript-eslint/utils" "5.14.0" debug "^4.3.2" tsutils "^3.21.0" -"@typescript-eslint/types@5.13.0": - version "5.13.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.13.0.tgz#da1de4ae905b1b9ff682cab0bed6b2e3be9c04e5" - integrity sha512-LmE/KO6DUy0nFY/OoQU0XelnmDt+V8lPQhh8MOVa7Y5k2gGRd6U9Kp3wAjhB4OHg57tUO0nOnwYQhRRyEAyOyg== +"@typescript-eslint/types@5.14.0": + version "5.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.14.0.tgz#96317cf116cea4befabc0defef371a1013f8ab11" + integrity sha512-BR6Y9eE9360LNnW3eEUqAg6HxS9Q35kSIs4rp4vNHRdfg0s+/PgHgskvu5DFTM7G5VKAVjuyaN476LCPrdA7Mw== -"@typescript-eslint/typescript-estree@5.13.0": - version "5.13.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.13.0.tgz#b37c07b748ff030a3e93d87c842714e020b78141" - integrity sha512-Q9cQow0DeLjnp5DuEDjLZ6JIkwGx3oYZe+BfcNuw/POhtpcxMTy18Icl6BJqTSd+3ftsrfuVb7mNHRZf7xiaNA== +"@typescript-eslint/typescript-estree@5.14.0": + version "5.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.14.0.tgz#78b7f7385d5b6f2748aacea5c9b7f6ae62058314" + integrity sha512-QGnxvROrCVtLQ1724GLTHBTR0lZVu13izOp9njRvMkCBgWX26PKvmMP8k82nmXBRD3DQcFFq2oj3cKDwr0FaUA== dependencies: - "@typescript-eslint/types" "5.13.0" - "@typescript-eslint/visitor-keys" "5.13.0" + "@typescript-eslint/types" "5.14.0" + "@typescript-eslint/visitor-keys" "5.14.0" debug "^4.3.2" globby "^11.0.4" is-glob "^4.0.3" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/utils@5.13.0": - version "5.13.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.13.0.tgz#2328feca700eb02837298339a2e49c46b41bd0af" - integrity sha512-+9oHlPWYNl6AwwoEt5TQryEHwiKRVjz7Vk6kaBeD3/kwHE5YqTGHtm/JZY8Bo9ITOeKutFaXnBlMgSATMJALUQ== +"@typescript-eslint/utils@5.14.0": + version "5.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.14.0.tgz#6c8bc4f384298cbbb32b3629ba7415f9f80dc8c4" + integrity sha512-EHwlII5mvUA0UsKYnVzySb/5EE/t03duUTweVy8Zqt3UQXBrpEVY144OTceFKaOe4xQXZJrkptCf7PjEBeGK4w== dependencies: "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.13.0" - "@typescript-eslint/types" "5.13.0" - "@typescript-eslint/typescript-estree" "5.13.0" + "@typescript-eslint/scope-manager" "5.14.0" + "@typescript-eslint/types" "5.14.0" + "@typescript-eslint/typescript-estree" "5.14.0" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/visitor-keys@5.13.0": - version "5.13.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.13.0.tgz#f45ff55bcce16403b221ac9240fbeeae4764f0fd" - integrity sha512-HLKEAS/qA1V7d9EzcpLFykTePmOQqOFim8oCvhY3pZgQ8Hi38hYpHd9e5GN6nQBFQNecNhws5wkS9Y5XIO0s/g== +"@typescript-eslint/visitor-keys@5.14.0": + version "5.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.14.0.tgz#1927005b3434ccd0d3ae1b2ecf60e65943c36986" + integrity sha512-yL0XxfzR94UEkjBqyymMLgCBdojzEuy/eim7N9/RIcTNxpJudAcqsU8eRyfzBbcEzGoPWfdM3AGak3cN08WOIw== dependencies: - "@typescript-eslint/types" "5.13.0" + "@typescript-eslint/types" "5.14.0" eslint-visitor-keys "^3.0.0" abab@^2.0.3, abab@^2.0.5: From fd042f9b1a1030f8200b4347d5f2a3ecee2fcbf2 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 9 Mar 2022 10:51:24 +0100 Subject: [PATCH 16/19] docs: update semver format after discussion and alignment --- website/docs/advanced/strategy-constraints.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/website/docs/advanced/strategy-constraints.md b/website/docs/advanced/strategy-constraints.md index 0311783f60..500780a339 100644 --- a/website/docs/advanced/strategy-constraints.md +++ b/website/docs/advanced/strategy-constraints.md @@ -135,12 +135,9 @@ String operators differ from the other categories in two different ways: The SemVer operators are used to compare version numbers such as application versions, dependency versions, etc. The SemVer input must follow a few rules: -- The value you enter must at least consist of three version numbers separated by full stops. Example: `1.2.3` +- The value you enter **must** start with and contain at least major, minor, and patch versions: Example: `1.2.3` - Optionally, you can also add pre-release version information by adding a hyphen and series of dot separated identifiers after the patch version. Example: `1.2.3-rc.2` -You can enter SemVer values with or without a leading "v": `v1.2.3` and `1.2.3` are both valid. -Importantly, they are also considered equal. - Versions with pre-release indicators (e.g. `4.8.0-rc.2`) are considered *less than* versions without (e.g. `4.8.0`) in accordance with [the SemVer specification, item 11](https://semver.org/#spec-item-11). You can read more about SemVer in [the full SemVer specification](https://semver.org/). From 52281512ac314ba22f6ccfc717e0e40a9dd786ef Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 9 Mar 2022 10:56:48 +0100 Subject: [PATCH 17/19] Apply suggestions from code review Co-authored-by: Fredrik Strand Oseberg --- website/docs/advanced/strategy-constraints.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/advanced/strategy-constraints.md b/website/docs/advanced/strategy-constraints.md index 500780a339..fd07a14a62 100644 --- a/website/docs/advanced/strategy-constraints.md +++ b/website/docs/advanced/strategy-constraints.md @@ -33,7 +33,7 @@ To be able to constrain on a field, it must be listed under the Context Field me Unleash only provides a limited set of context fields by default, and they may not fulfill all your needs. By using [custom context fields](../user_guide/unleash_context#custom-context-fields), you can tailor strategy constraints to your specific use case, such as: -- based on tenant IDs,release a feature to only specific tenants in a multi-tenant setup +- based on tenant IDs, release a feature to only specific tenants in a multi-tenant setup - release a feature to users in a specific region - release a feature only to beta testers From 613ee550bc201e302a81def02bbb1485cc4bd1f5 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 9 Mar 2022 11:55:21 +0100 Subject: [PATCH 18/19] docs: merge `currentTime` with "advanced constraints" row --- website/docs/sdks/index.md | 3 +-- website/docs/user_guide/unleash-context.md | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/website/docs/sdks/index.md b/website/docs/sdks/index.md index cb27b17189..de67d19eaa 100644 --- a/website/docs/sdks/index.md +++ b/website/docs/sdks/index.md @@ -76,12 +76,11 @@ If you see an item marked with a ❌ that you would find useful, feel free to re | Basic support | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | **Category: [Strategy constraints](../advanced/strategy_constraints)** | | | | | | | | | | | Basic support (`IN`, `NOT_IN` operators) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| Advanced support (Semver, date, numeric and extended string operators) | ✅ | ✅ | ⭕ | ⭕ | ⭕ | ⭕ | ✅ | ⭕ | | +| Advanced support (Semver, date, numeric and extended string operators) | ✅ | ✅ | ✅ | ✅ | ⭕ | ⭕ | ✅ | ⭕ | | | **Category: [Unleash Context](../user_guide/unleash_context)** | | | | | | | | | | | Static fields (`environment`, `appName`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | Defined fields | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | Custom properties | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | -| `currentTime` context field | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | ✅ | ✅ | | | **Category: [`isEnabled`](../client-specification#implementation-of-isenabled)** | | | | | | | | | | | Can take context | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | Override fallback value | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | diff --git a/website/docs/user_guide/unleash-context.md b/website/docs/user_guide/unleash-context.md index 1020c1235a..66a987634f 100644 --- a/website/docs/user_guide/unleash-context.md +++ b/website/docs/user_guide/unleash-context.md @@ -78,4 +78,4 @@ Any context field _can_ be used to [calculate custom stickiness](../advanced/sti [^1]: If you're on Unleash 4.3 or higher, you'll probably want to use [the environments feature](../user_guide/environments.md) instead of relying on the `environment` context field when working with environments. -[^2]: Check the [compatibility table](../sdks/index.md#current-time-server) for an overview of which SDKs provide the `currentTime` property. +[^2]: Check the [*strategy constraints: advanced support* row of the compatibility table](../sdks/index.md#strategy-constraints-advanced-support) for an overview of which SDKs provide the `currentTime` property. From ad9709f235429ef50843f713d0e8c4478e9614d8 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 9 Mar 2022 13:44:25 +0100 Subject: [PATCH 19/19] Tell the user what was available prior to 4.9 --- website/docs/advanced/strategy-constraints.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/advanced/strategy-constraints.md b/website/docs/advanced/strategy-constraints.md index fd07a14a62..8c42ad4a96 100644 --- a/website/docs/advanced/strategy-constraints.md +++ b/website/docs/advanced/strategy-constraints.md @@ -6,7 +6,7 @@ title: Strategy Constraints :::info Availability Strategy constraints are available to Unleash Pro and Enterprise users. -Unleash 4.9 introduced a more comprehensive set of constraint operators. These require that both Unleash *and* your client SDK of choice support them. See the [SDK compatibility table](../sdks/index.md#server-side-compatibility-table) for more information. +Unleash 4.9 introduced a more comprehensive set of constraint operators. These require that both Unleash *and* your client SDK of choice support them. See the [SDK compatibility table](../sdks/index.md#server-side-compatibility-table) for more information. Prior to Unleash 4.9, the only available operators were `IN` and `NOT_IN`. ::: :::tip