From 6923330e17ce7c07cfdd174ab4e569b72e7abde2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20L=C3=B3pez=20Dato?= Date: Wed, 23 Oct 2024 16:47:49 -0300 Subject: [PATCH 01/11] Resolve latest SDK versions at build time --- docs/docs/clients/index.md | 5 +- .../{server-side.md => server-side.mdx} | 344 ++++++++++-------- docs/docusaurus.config.js | 2 + docs/plugins/flagsmith-versions/index.js | 64 ++++ 4 files changed, 251 insertions(+), 164 deletions(-) rename docs/docs/clients/{server-side.md => server-side.mdx} (88%) create mode 100644 docs/plugins/flagsmith-versions/index.js diff --git a/docs/docs/clients/index.md b/docs/docs/clients/index.md index 9207cf086c81..db24ef74900f 100644 --- a/docs/docs/clients/index.md +++ b/docs/docs/clients/index.md @@ -47,7 +47,7 @@ Read more about our Client-side SDKs for your language/platform: ## Server-side SDKs -[Server-side SDKs](/clients/server-side.md) run within _trusted environments_ - typically the server infrastructure that +[Server-side SDKs](/clients/server-side) run within _trusted environments_ - typically the server infrastructure that you have control over. Because of this, you should not share your Server-side Environment keys publicly; they should be treated as secret. @@ -82,8 +82,7 @@ the Flag Engine, and the engine runs within your server environment within the F ![Local Evaluation Diagram](/img/sdk-local-evaluation.svg) You have to configure the SDK to run in Local Evaluation mode. See the -[SDK configuration options](server-side.md#configuring-the-sdk) for details on how to do that in your particular -language. +[SDK configuration options](server-side#configuring-the-sdk) for details on how to do that in your particular language. When the SDK is initialised in Local Evaluation mode, it grabs the entire set of details about the Environment from the Flagsmith API. For a given Environment, this includes: diff --git a/docs/docs/clients/server-side.md b/docs/docs/clients/server-side.mdx similarity index 88% rename from docs/docs/clients/server-side.md rename to docs/docs/clients/server-side.mdx index 74fda1bf0f7b..071bd52689f1 100644 --- a/docs/docs/clients/server-side.md +++ b/docs/docs/clients/server-side.mdx @@ -4,7 +4,16 @@ sidebar_label: Server Side sidebar_position: 2 --- -import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; +import CodeBlock from '@theme/CodeBlock'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +import { usePluginData } from '@docusaurus/useGlobalData'; +export const Version = ({ sdk }) => { + const version = usePluginData('flagsmith-versions')[sdk]; + if (!version) throw new Error('unknown sdk: ' + sdk); + return version; +}; # Server Side SDKs @@ -20,57 +29,57 @@ Server Side SDKs can run in 2 different modes: Local Evaluation and Remote Evalu -- Version Compatibility: **Python 3.8+** -- Source Code: https://github.com/Flagsmith/flagsmith-python-client +- Version Compatibility: **Python 3.8+** +- Source Code: https://github.com/Flagsmith/flagsmith-python-client -- Version Compatibility: **JDK 11+** -- Source Code: https://github.com/Flagsmith/flagsmith-java-client +- Version Compatibility: **JDK 11+** +- Source Code: https://github.com/Flagsmith/flagsmith-java-client -- Version Compatibility: **.NET core 6.0+** -- Source Code: https://github.com/Flagsmith/flagsmith-dotnet-client +- Version Compatibility: **.NET core 6.0+** +- Source Code: https://github.com/Flagsmith/flagsmith-dotnet-client -- Version Compatibility: **Node 14+** -- Source Code: - - https://github.com/Flagsmith/flagsmith-nodejs-client +- Version Compatibility: **Node 14+** +- Source Code: + - https://github.com/Flagsmith/flagsmith-nodejs-client -- Version Compatibility: **Ruby 2.4+** -- Source Code: https://github.com/Flagsmith/flagsmith-ruby-client +- Version Compatibility: **Ruby 2.4+** +- Source Code: https://github.com/Flagsmith/flagsmith-ruby-client -- Version Compatibility: **php 7.4+** -- Source Code: https://github.com/Flagsmith/flagsmith-php-client +- Version Compatibility: **php 7.4+** +- Source Code: https://github.com/Flagsmith/flagsmith-php-client -- Version Compatibility: **Go 1.18+** -- Source Code: https://github.com/Flagsmith/flagsmith-go-client +- Version Compatibility: **Go 1.18+** +- Source Code: https://github.com/Flagsmith/flagsmith-go-client -- Version Compatibility: **2021 edition (1.56.0)+** -- Source Code: https://github.com/Flagsmith/flagsmith-rust-client +- Version Compatibility: **2021 edition (1.56.0)+** +- Source Code: https://github.com/Flagsmith/flagsmith-rust-client -- Version Compatibility: **Elixir 1.12+** -- Source Code: https://github.com/Flagsmith/flagsmith-elixir-client +- Version Compatibility: **Elixir 1.12+** +- Source Code: https://github.com/Flagsmith/flagsmith-elixir-client @@ -87,39 +96,53 @@ pip install flagsmith -```xml -# Check https://search.maven.org/artifact/com.flagsmith/flagsmith-java-client -# for the latest version! +

Maven

-# Maven - - com.flagsmith - flagsmith-java-client - 7.2.0 - + + {` + com.flagsmith + flagsmith-java-client + `} + + {` +`} + -# Gradle -implementation 'com.flagsmith:flagsmith-java-client:7.2.0' -``` +

Gradle

+ + + {`implementation 'com.flagsmith:flagsmith-java-client:`} + + {`'`} +
-```bash -# Check https://www.nuget.org/packages/Flagsmith for the latest version! - -# Package Manager -Install-Package Flagsmith -Version 5.2.2 +

Package Manager console

+ + {`Install-Package Flagsmith -Version `} + + -#.NET CLI -dotnet add package Flagsmith --version 5.2.2 +

.NET CLI

+ + {`dotnet add package Flagsmith --version `} + + -# PackageReference - +

PackageReference

+ + {` + {`" />`} + -# Paket CLI -paket add Flagsmith --version 5.2.2 -``` +

Paket CLI

+ + {`paket add Flagsmith --version `} + +
@@ -156,32 +179,31 @@ composer require flagsmith/flagsmith-php-client symfony/http-client nyholm/psr7 ```bash -# Check https://github.com/Flagsmith/flagsmith-go-client/releases for the latest version! - -go get github.com/Flagsmith/flagsmith-go-client/v3 +go get github.com/Flagsmith/flagsmith-go-client ``` -```bash -# Check https://crates.io/crates/flagsmith/versions for the latest version! - -# Cargo.toml -[dependencies] -flagsmith = "~1" -``` + + {`[dependencies] +flagsmith = "~`} + + {`"`} + -```elixir -def deps do + + {`def deps do [ - {:flagsmith_engine, "~> 1.0"} + {:flagsmith_engine, "~> `} + + {`"}, ] -end -``` +end`} + @@ -234,7 +256,7 @@ _flagsmithClient = new("FLAGSMITH_SERVER_SIDE_ENVIRONMENT_KEY"); const Flagsmith = require('flagsmith-nodejs'); const flagsmith = new Flagsmith({ - environmentKey: 'FLAGSMITH_SERVER_SIDE_ENVIRONMENT_KEY', + environmentKey: 'FLAGSMITH_SERVER_SIDE_ENVIRONMENT_KEY', }); ``` @@ -555,19 +577,19 @@ secret_button_feature_value = Flagsmith.Client.get_feature_value(flags, "secret_ ### When running in [Remote Evaluation mode](/clients#remote-evaluation) -- When requesting Flags for an Identity, all the Traits defined in the SDK will automatically be persisted against the - Identity within the Flagsmith API. -- Traits passed to the SDK will be added to all the other previously persisted Traits associated with that Identity. -- This full set of Traits are then used to evaluate the Flag values for the Identity. -- This all happens in a single request/response. +- When requesting Flags for an Identity, all the Traits defined in the SDK will automatically be persisted against the + Identity within the Flagsmith API. +- Traits passed to the SDK will be added to all the other previously persisted Traits associated with that Identity. +- This full set of Traits are then used to evaluate the Flag values for the Identity. +- This all happens in a single request/response. ### When running in [Local Evaluation mode](/clients#local-evaluation) -- _Only_ the Traits provided to the SDK at runtime will be used. Local Evaluation mode, by design, does not make any - network requests to the Flagsmith API when evaluating Flags for an Identity. - - When running in Local Evaluation Mode, the SDK requests the - [Environment Document](/clients#the-environment-document) from the Flagsmith API. This contains all the information - required to make Flag Evaluations, but it does _not_ contain any Trait data. +- _Only_ the Traits provided to the SDK at runtime will be used. Local Evaluation mode, by design, does not make any + network requests to the Flagsmith API when evaluating Flags for an Identity. + - When running in Local Evaluation Mode, the SDK requests the + [Environment Document](/clients#the-environment-document) from the Flagsmith API. This contains all the + information required to make Flag Evaluations, but it does _not_ contain any Trait data. ## Managing Default Flags @@ -649,11 +671,11 @@ static Flag defaultFlagHandler(string featureName) ```javascript const flagsmith = new Flagsmith({ - environmentKey, - enableLocalEvaluation: true, - defaultFlagHandler: (str) => { - return { enabled: false, isDefault: true, value: { colour: '#ababab' } }; - }, + environmentKey, + enableLocalEvaluation: true, + defaultFlagHandler: (str) => { + return { enabled: false, isDefault: true, value: { colour: '#ababab' } }; + }, }); ``` @@ -767,8 +789,8 @@ Progress on the remaining SDKs can be seen [here](https://github.com/Flagsmith/f Flagsmith SDKs can be configured to include an offline handler which has 2 functions: -1. It can be used alongside [Offline Mode](server-side.md#offline-mode) to evaluate flags in environments with no - network access +1. It can be used alongside [Offline Mode](server-side#offline-mode) to evaluate flags in environments with no network + access 2. It can be used as a means of defining the behaviour for evaluating default flags, when something goes wrong with the regular evaluation process. To do this, simply set the offline handler initialisation parameter without enabling offline mode. @@ -966,10 +988,10 @@ The Server Side SDKS share the same network behaviour across the different langu ### Remote Evaluation Mode Network Behaviour -- A blocking network request is made every time you make a call to get an Environment Flags. In Python, for example, - `flagsmith.get_environment_flags()` will trigger this request. -- A blocking network request is made every time you make a call to get an Identities Flags. In Python, for example, - `flagsmith.get_identity_flags(identifier=identifier, traits=traits)` will trigger this request. +- A blocking network request is made every time you make a call to get an Environment Flags. In Python, for example, + `flagsmith.get_environment_flags()` will trigger this request. +- A blocking network request is made every time you make a call to get an Identities Flags. In Python, for example, + `flagsmith.get_identity_flags(identifier=identifier, traits=traits)` will trigger this request. ### Local Evaluation Mode Network Behaviour @@ -981,9 +1003,9 @@ To use Local Evaluation mode, you must use a Server Side key. ::: -- When the SDK is initialised, it will make an asynchronous network request to retrieve details about the Environment. -- Every 60 seconds (by default), it will repeat this aysnchronous request to ensure that the Environment information it - has is up to date. +- When the SDK is initialised, it will make an asynchronous network request to retrieve details about the Environment. +- Every 60 seconds (by default), it will repeat this aysnchronous request to ensure that the Environment information + it has is up to date. To achieve Local Evaluation, in most languages, the SDK spawns a separate thread (or equivalent) to poll the API for changes to the Environment. In certain languages, you may be required to terminate this thread before cleaning up the @@ -1027,8 +1049,8 @@ Progress on the remaining SDKs can be seen [here](https://github.com/Flagsmith/f To run the SDK in a fully offline mode, you can set the client to offline mode. This will prevent the SDK from making any calls to the Flagsmith API. To use offline mode, you must also provide an -[offline handler](server-side.md#using-an-offline-handler). See -[Configuring the SDK](server-side.md#configuring-the-sdk) for more details on initialising the SDK in offline mode. +[offline handler](server-side#using-an-offline-handler). See [Configuring the SDK](server-side#configuring-the-sdk) for +more details on initialising the SDK in offline mode. ## Configuring the SDK @@ -1324,15 +1346,15 @@ In the `appsettings.json` file you can configure the necessary flagsmith values. ```json { - "AllowedHosts": "*", - "FlagsmithConfiguration": { - "EnvironmentKey": "FLAGSMITH_SERVER_SIDE_ENVIRONMENT_KEY", - "EnableClientSideEvaluation": false, - "EnvironmentRefreshIntervalSeconds": 60, - "EnableAnalytics": true, - "RequestTimeout": 10, - "Retries": 3 - } + "AllowedHosts": "*", + "FlagsmithConfiguration": { + "EnvironmentKey": "FLAGSMITH_SERVER_SIDE_ENVIRONMENT_KEY", + "EnableClientSideEvaluation": false, + "EnvironmentRefreshIntervalSeconds": 60, + "EnableAnalytics": true, + "RequestTimeout": 10, + "Retries": 3 + } } ``` @@ -1402,83 +1424,83 @@ $flagsmith = Flagsmith::Client.new( import { bool, number } from 'prop-types'; const flagsmith = new Flagsmith({ - /* + /* Your API Token. Note that this is either the `Environment API` key or the `Server Side SDK Token` depending on if you are using Local or Remote Evaluation Required. */ - environmentKey: 'FLAGSMITH_SERVER_SIDE_ENVIRONMENT_KEY', + environmentKey: 'FLAGSMITH_SERVER_SIDE_ENVIRONMENT_KEY', - /* + /* Override the default Flagsmith API URL if you are self-hosting. Optional. Defaults to https://edge.api.flagsmith.com/api/v1/ */ - apiUrl: 'https://api.yourselfhostedflagsmith.com/api/v1/', + apiUrl: 'https://api.yourselfhostedflagsmith.com/api/v1/', - /* + /* Adds caching support Optional See https://docs.flagsmith.com/clients/server-side#caching */ - cache: { - has: (key: string) => bool, - get: (key: string) => string | number | null, - set: (k: string, v: Flags) => (cache[k] = v), - }, + cache: { + has: (key: string) => bool, + get: (key: string) => string | number | null, + set: (k: string, v: Flags) => (cache[k] = v), + }, - /* + /* Custom http headers can be added to the http client Optional */ - customHeaders: { aHeader: 'aValue' }, + customHeaders: { aHeader: 'aValue' }, - /* + /* Controls whether Flag Analytics data is sent to the Flagsmith API See https://docs.flagsmith.com/advanced-use/flag-analytics Optional Defaults to false */ - enableAnalytics: true, + enableAnalytics: true, - /* + /* Controls which mode to run in; local or remote evaluation. See the `SDKs Overview Page` for more info Optional. Defaults to false. */ - enableLocalEvaluation: true, + enableLocalEvaluation: true, - /* + /* Set environment refresh rate with polling manager. Only needed when local evaluation is true. Optional. Defaults to 60 seconds */ - environmentRefreshIntervalSeconds: 60, + environmentRefreshIntervalSeconds: 60, - /* + /* The network timeout in seconds. Optional. Defaults to 10 seconds */ - requestTimeoutSeconds: 30, + requestTimeoutSeconds: 30, - /* + /* You can specify default Flag values on initialisation. Optional */ - defaultFlagHandler: (featureName: string) => { - return { enabled: false, isDefault: true, value: null }; - }, + defaultFlagHandler: (featureName: string) => { + return { enabled: false, isDefault: true, value: null }; + }, - /* + /* A callback for whenever the environment model is updated or there is an error retrieving it. This is only used in local evaluation mode. Optional */ - onEnvironmentChange: (error: Error | null, result: EnvironmentModel) => {}, + onEnvironmentChange: (error: Error | null, result: EnvironmentModel) => {}, }); ``` @@ -1776,9 +1798,9 @@ Flagsmith uses [Caffeine](https://github.com/ben-manes/caffeine), a high perform If you enable caching on the Flagsmith client without setting any values (as shown below), the following default values will be set for you: -- `maxSize(10)` -- `expireAfterWrite(5, TimeUnit.MINUTES)` -- project level caching will be disabled by default (i.e. only enabled if you configure a caching key) +- `maxSize(10)` +- `expireAfterWrite(5, TimeUnit.MINUTES)` +- project level caching will be disabled by default (i.e. only enabled if you configure a caching key) ```java // use in-memory caching with Flagsmith defaults as described above @@ -1881,44 +1903,44 @@ const flagsmith = require('flagsmith-nodejs'); const redis = require('redis'); const redisClient = redis.createClient({ - host: 'localhost', - port: 6379, + host: 'localhost', + port: 6379, }); flagsmith.init({ - environmentID: 'FLAGSMITH_SERVER_SIDE_ENVIRONMENT_KEY', - cache: { - has: (key) => - new Promise((resolve, reject) => { - redisClient.exists(key, (err, reply) => { - console.log('check ' + key + ' from cache', err, reply); - resolve(reply === 1); - }); - }), - get: (key) => - new Promise((resolve) => { - redisClient.get(key, (err, cacheValue) => { - console.log('get ' + key + ' from cache'); - resolve(cacheValue && JSON.parse(cacheValue)); - }); - }), - set: (key, value) => - new Promise((resolve) => { - // Expire the key after 60 seconds - redisClient.set(key, JSON.stringify(value), 'EX', 60, (err, reply) => { - console.log('set ' + key + ' to cache', err); - resolve(); - }); - }), - }, + environmentID: 'FLAGSMITH_SERVER_SIDE_ENVIRONMENT_KEY', + cache: { + has: (key) => + new Promise((resolve, reject) => { + redisClient.exists(key, (err, reply) => { + console.log('check ' + key + ' from cache', err, reply); + resolve(reply === 1); + }); + }), + get: (key) => + new Promise((resolve) => { + redisClient.get(key, (err, cacheValue) => { + console.log('get ' + key + ' from cache'); + resolve(cacheValue && JSON.parse(cacheValue)); + }); + }), + set: (key, value) => + new Promise((resolve) => { + // Expire the key after 60 seconds + redisClient.set(key, JSON.stringify(value), 'EX', 60, (err, reply) => { + console.log('set ' + key + ' to cache', err); + resolve(); + }); + }), + }, }); router.get('/', function (req, res, next) { - flagsmith.getValue('background_colour').then((value) => { - res.render('index', { - title: value, - }); - }); + flagsmith.getValue('background_colour').then((value) => { + res.render('index', { + title: value, + }); + }); }); ``` @@ -1961,11 +1983,11 @@ $flagsmith->updateEnvironment(); Note: -- For the environment cache, please use the server key generated from the Flagsmith Settings menu. The key's prefix is - `ser.`. -- The cache is important for concurrent requests. Without the cache, each request in PHP is a different process with its - own memory objects. The cache (filesystem or other) would enforce that the network call is reduced to a file system - one. +- For the environment cache, please use the server key generated from the Flagsmith Settings menu. The key's prefix is + `ser.`. +- The cache is important for concurrent requests. Without the cache, each request in PHP is a different process with + its own memory objects. The cache (filesystem or other) would enforce that the network call is reduced to a file + system one. diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index c4acdfa829e3..cf9fc701afb8 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -240,6 +240,8 @@ const config = { ], clientModules: [require.resolve('./plugins/crisp-chat-links.js')], + + plugins: ['./plugins/flagsmith-versions'], }; export default config; diff --git a/docs/plugins/flagsmith-versions/index.js b/docs/plugins/flagsmith-versions/index.js new file mode 100644 index 000000000000..7c412b91999b --- /dev/null +++ b/docs/plugins/flagsmith-versions/index.js @@ -0,0 +1,64 @@ +const fetchJSON = async (url, options) => { + const response = await fetch(url, options); + if (!response.ok) throw new Error(await response.text()); + return response.json(); +}; + +const fallback = (value) => (promise) => { + if (!process.env.CI) + return promise.catch((e) => { + console.error(e); + return value; + }); + return promise; +}; + +const fetchJavaVersion = async () => { + const data = await fetchJSON( + 'https://search.maven.org/solrsearch/select?q=g:%22com.flagsmith%22+AND+a:%22flagsmith-java-client%22&wt=json', + ); + if (data.response.numFound !== 1) throw new Error('unexpected response when fetching Java version', data); + return data.response.docs[0].latestVersion; +}; + +const fetchDotnetVersion = async () => { + const data = await fetchJSON('https://api.nuget.org/v3-flatcontainer/Flagsmith/index.json'); + return data.versions[data.versions.length - 1]; +}; + +const fetchRustVersion = async () => { + // https://crates.io/data-access#api + const headers = new Headers({ + 'User-Agent': 'Flagsmith-Docs ', + }); + const data = await fetchJSON('https://crates.io/api/v1/crates/flagsmith', { headers }); + return data.crate.max_stable_version; +}; + +const fetchElixirVersion = async () => { + const data = await fetchJSON('https://hex.pm/api/packages/flagsmith_engine'); + return data.releases[0].version; +}; + +export default async function fetchFlagsmithVersions(context, options) { + return { + name: 'flagsmith-versions', + async loadContent() { + const [java, dotnet, rust, elixir] = await Promise.all( + [fetchJavaVersion(), fetchDotnetVersion(), fetchRustVersion(), fetchElixirVersion()].map( + fallback('x.y.z'), + ), + ); + return { + java, + dotnet, + rust, + elixir, + }; + }, + async contentLoaded({ content, actions }) { + const { setGlobalData } = actions; + setGlobalData(content); + }, + }; +} From ebd94656bcdbbeb41142196f819df91d03efaf18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20L=C3=B3pez=20Dato?= Date: Wed, 23 Oct 2024 17:37:35 -0300 Subject: [PATCH 02/11] Use lowercase nuget package ID --- docs/plugins/flagsmith-versions/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plugins/flagsmith-versions/index.js b/docs/plugins/flagsmith-versions/index.js index 7c412b91999b..f56a08c1d13a 100644 --- a/docs/plugins/flagsmith-versions/index.js +++ b/docs/plugins/flagsmith-versions/index.js @@ -22,7 +22,7 @@ const fetchJavaVersion = async () => { }; const fetchDotnetVersion = async () => { - const data = await fetchJSON('https://api.nuget.org/v3-flatcontainer/Flagsmith/index.json'); + const data = await fetchJSON('https://api.nuget.org/v3-flatcontainer/flagsmith/index.json'); return data.versions[data.versions.length - 1]; }; From ed4365d958cc51baa1f20a44573146222a45e97e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20L=C3=B3pez=20Dato?= Date: Thu, 24 Oct 2024 16:16:25 -0300 Subject: [PATCH 03/11] Add major version specs for serverside SDKs Also extract SDK version components to separate file --- docs/docs/clients/server-side.mdx | 23 +++++++++-------------- docs/docusaurus.config.js | 1 + docs/plugins/flagsmith-versions/index.js | 23 +++++++++++------------ docs/src/components/SdkVersions.js | 23 +++++++++++++++++++++++ 4 files changed, 44 insertions(+), 26 deletions(-) create mode 100644 docs/src/components/SdkVersions.js diff --git a/docs/docs/clients/server-side.mdx b/docs/docs/clients/server-side.mdx index 071bd52689f1..68409bb4d29c 100644 --- a/docs/docs/clients/server-side.mdx +++ b/docs/docs/clients/server-side.mdx @@ -8,12 +8,7 @@ import CodeBlock from '@theme/CodeBlock'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -import { usePluginData } from '@docusaurus/useGlobalData'; -export const Version = ({ sdk }) => { - const version = usePluginData('flagsmith-versions')[sdk]; - if (!version) throw new Error('unknown sdk: ' + sdk); - return version; -}; +import { JavaVersion, RustVersion, DotnetVersion, ElixirVersion } from '@site/src/components/SdkVersions.js'; # Server Side SDKs @@ -103,7 +98,7 @@ pip install flagsmith com.flagsmith flagsmith-java-client `} - + {` `} @@ -112,7 +107,7 @@ pip install flagsmith {`implementation 'com.flagsmith:flagsmith-java-client:`} - + {`'`} @@ -122,26 +117,26 @@ pip install flagsmith

Package Manager console

{`Install-Package Flagsmith -Version `} - +

.NET CLI

{`dotnet add package Flagsmith --version `} - +

PackageReference

{` + {`" />`}

Paket CLI

{`paket add Flagsmith --version `} - + @@ -188,7 +183,7 @@ go get github.com/Flagsmith/flagsmith-go-client {`[dependencies] flagsmith = "~`} - + {`"`} @@ -199,7 +194,7 @@ flagsmith = "~`} {`def deps do [ {:flagsmith_engine, "~> `} - + {`"}, ] end`} diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index cf9fc701afb8..aaa6a047039f 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -209,6 +209,7 @@ const config = { customFields: { swaggerURL: '/api-static/edge-api.yaml', + CI: process.env.CI, }, presets: [ diff --git a/docs/plugins/flagsmith-versions/index.js b/docs/plugins/flagsmith-versions/index.js index f56a08c1d13a..8881e9df829d 100644 --- a/docs/plugins/flagsmith-versions/index.js +++ b/docs/plugins/flagsmith-versions/index.js @@ -13,31 +13,30 @@ const fallback = (value) => (promise) => { return promise; }; -const fetchJavaVersion = async () => { +const fetchJavaVersions = async () => { const data = await fetchJSON( - 'https://search.maven.org/solrsearch/select?q=g:%22com.flagsmith%22+AND+a:%22flagsmith-java-client%22&wt=json', + 'https://search.maven.org/solrsearch/select?q=g:%22com.flagsmith%22+AND+a:%22flagsmith-java-client%22&wt=json&core=gav', ); - if (data.response.numFound !== 1) throw new Error('unexpected response when fetching Java version', data); - return data.response.docs[0].latestVersion; + return data.response.docs.map((doc) => doc.v); }; -const fetchDotnetVersion = async () => { +const fetchDotnetVersions = async () => { const data = await fetchJSON('https://api.nuget.org/v3-flatcontainer/flagsmith/index.json'); - return data.versions[data.versions.length - 1]; + return data.versions; }; -const fetchRustVersion = async () => { +const fetchRustVersions = async () => { // https://crates.io/data-access#api const headers = new Headers({ 'User-Agent': 'Flagsmith-Docs ', }); const data = await fetchJSON('https://crates.io/api/v1/crates/flagsmith', { headers }); - return data.crate.max_stable_version; + return data.versions.map((version) => version.num); }; -const fetchElixirVersion = async () => { +const fetchElixirVersions = async () => { const data = await fetchJSON('https://hex.pm/api/packages/flagsmith_engine'); - return data.releases[0].version; + return data.releases.map((release) => release.version); }; export default async function fetchFlagsmithVersions(context, options) { @@ -45,8 +44,8 @@ export default async function fetchFlagsmithVersions(context, options) { name: 'flagsmith-versions', async loadContent() { const [java, dotnet, rust, elixir] = await Promise.all( - [fetchJavaVersion(), fetchDotnetVersion(), fetchRustVersion(), fetchElixirVersion()].map( - fallback('x.y.z'), + [fetchJavaVersions(), fetchDotnetVersions(), fetchRustVersions(), fetchElixirVersions()].map( + fallback([]), ), ); return { diff --git a/docs/src/components/SdkVersions.js b/docs/src/components/SdkVersions.js new file mode 100644 index 000000000000..988a1bb06080 --- /dev/null +++ b/docs/src/components/SdkVersions.js @@ -0,0 +1,23 @@ +import { usePluginData } from '@docusaurus/useGlobalData'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import { maxSatisfying } from 'semver'; + +export const Version = ({ sdk, spec = '*' }) => { + const { + siteConfig: { CI }, + } = useDocusaurusContext(); + const versions = usePluginData('flagsmith-versions')[sdk]; + if (!versions) throw new Error('unknown sdk: ' + sdk); + const latest = maxSatisfying(versions, spec); + if (latest === null) { + const message = `no version found for ${sdk} that matches ${spec}. available versions: [${versions.join(', ')}]`; + if (CI) throw new Error(message); + console.error(message); + } + return latest ?? 'x.y.z'; +}; + +export const JavaVersion = ({ spec = '~7' }) => Version({ sdk: 'java', spec }); +export const DotnetVersion = ({ spec = '~5' }) => Version({ sdk: 'dotnet', spec }); +export const ElixirVersion = ({ spec = '~2' }) => Version({ sdk: 'elixir', spec }); +export const RustVersion = ({ spec = '~2' }) => Version({ sdk: 'rust', spec }); From 1fefe3bedb0f2a1f0af7819283f184791a951f6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20L=C3=B3pez=20Dato?= Date: Thu, 24 Oct 2024 16:42:02 -0300 Subject: [PATCH 04/11] Add client-side JS version --- docs/docs/quickstart.md | 16 ++++++++-------- docs/plugins/flagsmith-versions/index.js | 18 ++++++++++++++---- docs/src/components/SdkVersions.js | 1 + 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/docs/docs/quickstart.md b/docs/docs/quickstart.md index 4e76d2868c76..0b409d17ab64 100644 --- a/docs/docs/quickstart.md +++ b/docs/docs/quickstart.md @@ -3,6 +3,8 @@ sidebar_position: 2 sidebar_label: Quick Start --- +import CodeBlock from '@theme/CodeBlock'; import { JsVersion } from '@site/src/components/SdkVersions.js'; + # Flagsmith Quick Start Guide Let's get up and running in 5 minutes. We're going to run through the following steps: @@ -68,9 +70,7 @@ The page looks like this: For the purposes of this quickstart tutorial, we will import the SDK inline into our web page: -```html - -``` +{ `` } ## 3. Connect to the Flagsmith API @@ -121,13 +121,13 @@ the state of the flag and set the display visibility based on the result. Our entire webpage now reads like this: -```html - +{ ` + Flagsmith Quickstart Guide - +