mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
Fixed syntax highlighting in the docs (#6678)
Adds support for Svelte syntax highlighting and lets us add support for additional languages in the future
This commit is contained in:
parent
888a5c1283
commit
8a9d013545
@ -9,7 +9,6 @@ This article is a contribution by **[Ayush Bherwani](https://www.linkedin.com/in
|
||||
|
||||
:::
|
||||
|
||||
|
||||
After successfully integrating the first feature flag in the Unsplash sample app, let’s talk about how you can use Unleash to perform experimentation, also known as A/B testing, in Flutter to ship features more confidently.
|
||||
|
||||
For this article, we’ll integrate feature flags for A/B testing to experiment with “like image” feature user experience. As an overview, the app is quite simple, with two screens displaying images and image details respectively. The behavior of the “image details” feature is controlled through an Unleash instance. You can check out the previous article, “[How to set up feature flags in Flutter](https://www.getunleash.io/blog/from-the-community-how-to-set-up-feature-flags-in-flutter)” for an overview of the code structure and implementation. For those who want to skip straight to the code, you can find it on [GitHub](https://github.com/AyushBherwani1998/unsplash_sample/).
|
||||
@ -17,35 +16,29 @@ For this article, we’ll integrate feature flags for A/B testing to experiment
|
||||
Here’s a screenshot of the application:
|
||||
![Unsplash App built on Flutter](/img/unsplash-demo-flutter.png)
|
||||
|
||||
|
||||
## Setup variants in Unleash
|
||||
|
||||
|
||||
In your Unleash instance, create a new feature flag called `likeOptionExperiment`. Choose the toggle type called `Experiment` and enable the [impression data](https://docs.getunleash.io/reference/impression-data). By default, the flag will be set to false.
|
||||
|
||||
![Set Up Variant in Unleash](/img/variant-setup-1.png)
|
||||
|
||||
|
||||
Now that you have created your feature toggle, let’s create two new [variants](https://docs.getunleash.io/reference/feature-toggle-variants) “gridTile'' and “imageDetails” respectively. These variants will help you position your “like image” button.
|
||||
Now that you have created your feature toggle, let’s create two new [variants](https://docs.getunleash.io/reference/feature-toggle-variants) “gridTile'' and “imageDetails” respectively. These variants will help you position your “like image” button.
|
||||
|
||||
![Succesfully setting up variant in Unleash](/img/setup-variant-2.png)
|
||||
|
||||
|
||||
Below is a screenshot of experimentation in action based on the `likeOptionExperiment` flag and corresponding variants.
|
||||
Below is a screenshot of experimentation in action based on the `likeOptionExperiment` flag and corresponding variants.
|
||||
|
||||
![Unsplash App built on Flutter](/img/unsplash-flutter-demo-screenshot-2.png)
|
||||
|
||||
|
||||
## Setup Mixpanel
|
||||
|
||||
For analytics and metrics, we’ll use [Mixpanel](https://mixpanel.com/) to track user behavior and usage patterns. We have chosen Mixpanel because it offers a user-friendly setup and in-depth user analytics and segmentation. Given that the project follows clean architecture and Test-Driven Development (TDD) principles, you’ll want to create an abstract layer to interact with the Mixpanel.
|
||||
|
||||
Whenever a user opens the app, we track `like-variant` if `likeOptionExperiment` is enabled to tag them with their assigned variant (gridTile or imageDetails). The stored variant in Mixpanel can be used later to analyze how each variant impacts user behavior to like an image.
|
||||
|
||||
Whenever a user interacts with the `LikeButton`, we track `trackLikeEventForExperimentation`, along with their assigned variants. By correlating the `trackLikeEventForExperimentation` with the `like-variant`, you can effectively measure the impact of a variant on user behavior and make data-driven decisions. To learn how to correlate and generate reports, see the [Mixpanel docs](https://docs.mixpanel.com/docs/analysis/reports).
|
||||
Whenever a user interacts with the `LikeButton`, we track `trackLikeEventForExperimentation`, along with their assigned variants. By correlating the `trackLikeEventForExperimentation` with the `like-variant`, you can effectively measure the impact of a variant on user behavior and make data-driven decisions. To learn how to correlate and generate reports, see the [Mixpanel docs](https://docs.mixpanel.com/docs/analysis/reports).
|
||||
|
||||
|
||||
```
|
||||
```dart
|
||||
abstract class MixpanelConfig {
|
||||
/// ...
|
||||
|
||||
@ -96,17 +89,15 @@ class MixpanelConfigImpl implements MixpanelConfig {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Once you have your configuration in place, the next step is to create `MixPanel` and `MixpanelConfig` and add it to your service locator class. Make sure that you have a Mixpanel[ API key](https://docs.mixpanel.com/docs/tracking/how-tos/api-credentials).
|
||||
|
||||
|
||||
```
|
||||
```dart
|
||||
class ServiceLocator {
|
||||
ServiceLocator._();
|
||||
|
||||
static GetIt get getIt => GetIt.instance;
|
||||
|
||||
static Future<void> initialize() async {
|
||||
static Future<void> initialize() async {
|
||||
/// ...
|
||||
|
||||
final unleash = UnleashClient(
|
||||
@ -152,15 +143,13 @@ class ServiceLocator {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Integration in Flutter
|
||||
|
||||
Let’s dive into how you can use these variants in your Flutter application.
|
||||
Let’s dive into how you can use these variants in your Flutter application.
|
||||
|
||||
You’ll have to modify `UnleashConfig` which helps you test the Unleash functionalities in isolation from the rest of the app.
|
||||
|
||||
|
||||
```
|
||||
```dart
|
||||
const String isImageDetailsEnabledToggleKey = "isImageDetailsEnabled";
|
||||
const String likeOptionExperimentKey = "likeOptionExperiment";
|
||||
|
||||
@ -196,11 +185,9 @@ class UnleashConfigImpl extends UnleashConfig {
|
||||
}
|
||||
```
|
||||
|
||||
After updating `UnleashConfig` you may want to create a `_trackLikeExperimentationVariant` method which you can call in `initState` of “HomePage” to get the variant details.
|
||||
|
||||
After updating `UnleashConfig` you may want to create a `_trackLikeExperimentationVariant` method which you can call in `initState` of “HomePage” to get the variant details.
|
||||
|
||||
|
||||
```
|
||||
```dart
|
||||
void _trackLikeExperimentationVariant() {
|
||||
final unleashConfig = ServiceLocator.getIt<UnleashConfig>();
|
||||
final mixpanelConfig = ServiceLocator.getIt<MixpanelConfig>();
|
||||
@ -210,11 +197,9 @@ void _trackLikeExperimentationVariant() {
|
||||
}
|
||||
```
|
||||
|
||||
You’ll create a new widget “LikeButton'' which can be utilized for both variants. Make sure to use `MixpanelConfig` to track user engagement for analytics purposes.
|
||||
|
||||
You’ll create a new widget “LikeButton'' which can be utilized for both variants. Make sure to use `MixpanelConfig` to track user engagement for analytics purposes.
|
||||
|
||||
|
||||
```
|
||||
```dart
|
||||
class LikeButton extends StatelessWidget {
|
||||
final ValueNotifier<bool> isLikedNotifier;
|
||||
/// Used to track the variant option for the mixpanel event.
|
||||
@ -265,13 +250,11 @@ class LikeButton extends StatelessWidget {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Once you have created `LikeButton`, the next step is to use the `LikeButtonPosition` to add the button in the `ImageTile` widget, and `ImageDetails` page.
|
||||
Once you have created `LikeButton`, the next step is to use the `LikeButtonPosition` to add the button in the `ImageTile` widget, and `ImageDetails` page.
|
||||
|
||||
For `ImageTile` make sure the button is only visible if `isLikeOptionExperiment` is enabled and `LikeButtonPosition` is `gridTile`.
|
||||
|
||||
|
||||
```
|
||||
```dart
|
||||
class ImageTile extends StatelessWidget {
|
||||
final UnsplashImage image;
|
||||
final UnleashConfig unleashConfig;
|
||||
@ -309,11 +292,9 @@ class ImageTile extends StatelessWidget {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
For `ImageDetailsPage` make sure the button is only visible if `isLikeOptionExperiment` is enabled and `LikeButtonPosition` is `imageDetails`.
|
||||
|
||||
|
||||
```
|
||||
```dart
|
||||
@RoutePage()
|
||||
class ImageDetailsPage extends StatefulWidget {
|
||||
final String id;
|
||||
@ -382,33 +363,27 @@ class _ImageDetailsPageState extends State<ImageDetailsPage> {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Now that you have your pieces clubbed, you can toggle the `likeOptionExperiment` flag to enable the experimentation of the “like image” feature in the application.
|
||||
Now that you have your pieces clubbed, you can toggle the `likeOptionExperiment` flag to enable the experimentation of the “like image” feature in the application.
|
||||
|
||||
Voila! Your experimentation is enabled for your feature. You’ve also ensured that users can access the “like image” feature depending on the state of the flag and variant.
|
||||
|
||||
## Analytics
|
||||
|
||||
|
||||
Once your experimentation is up and running, you can visit the Mixpanel dashboard to create a [funnel](https://docs.mixpanel.com/docs/analysis/reports/funnels) and get insights on the user engagement and conversion rate for different variants.
|
||||
Once your experimentation is up and running, you can visit the Mixpanel dashboard to create a [funnel](https://docs.mixpanel.com/docs/analysis/reports/funnels) and get insights on the user engagement and conversion rate for different variants.
|
||||
|
||||
Below is a funnel screenshot for “like image” experimentation:
|
||||
|
||||
![Mixpanel Analytics for A/B Testing in Unleash for the Flutter Demo](/img/mixpanel-flutter-screenshot-1.png)
|
||||
|
||||
|
||||
## Conclusion
|
||||
|
||||
|
||||
A/B testing is a low-risk, high-returns approach that can help you make data-driven decisions for your feature releases to increase user engagement, minimize the risk, and increase conversion rates. As a developer, it helps you be confident in your releases by addressing the issues users face and reducing the bounce rates during experimentation with the help of data.
|
||||
A/B testing is a low-risk, high-returns approach that can help you make data-driven decisions for your feature releases to increase user engagement, minimize the risk, and increase conversion rates. As a developer, it helps you be confident in your releases by addressing the issues users face and reducing the bounce rates during experimentation with the help of data.
|
||||
|
||||
Some of the best practices for experimentation include:
|
||||
|
||||
|
||||
|
||||
* You should be open to the results and avoid any hypotheses.
|
||||
* You should define the metrics for the success of the experimentation before you run the tests. Keep your success metrics simple and narrowed for better results.
|
||||
* Select a group of adequate size for the test to yield definitive results.
|
||||
* You should avoid running multiple tests simultaneously, as it may not give reasonable outcomes.
|
||||
- You should be open to the results and avoid any hypotheses.
|
||||
- You should define the metrics for the success of the experimentation before you run the tests. Keep your success metrics simple and narrowed for better results.
|
||||
- Select a group of adequate size for the test to yield definitive results.
|
||||
- You should avoid running multiple tests simultaneously, as it may not give reasonable outcomes.
|
||||
|
||||
That’s it for today. I hope you found this helpful. Want to dive deep into the code used for this article? It’s all on [GitHub](https://github.com/AyushBherwani1998/unsplash_sample/).
|
||||
|
@ -11,13 +11,10 @@ This article is a contribution by **[Kafilat Adeleke](https://www.linkedin.com/i
|
||||
|
||||
Imagine turning on and off features in your web application without redeploying your code. Sounds too good to be true? It's possible with feature flags and Next.js, a powerful framework for building fast and scalable web applications using React.
|
||||
|
||||
|
||||
Feature flags are a powerful technique that allows you to toggle features on and off dynamically without redeploying your code. This can help you to deliver faster and safer web applications, as you can test new features in production, perform gradual rollouts, and revert changes quickly if something goes wrong.
|
||||
|
||||
|
||||
Next.js provides features such as:
|
||||
|
||||
|
||||
- Server-side rendering
|
||||
- Static site generation
|
||||
- Code splitting
|
||||
@ -26,24 +23,18 @@ Next.js provides features such as:
|
||||
- CSS modules support
|
||||
- And many more
|
||||
|
||||
|
||||
With Next.js, you can create hybrid applications that can use both static and dynamic pages. Static pages are pre-rendered at build time and served from a CDN, which makes them fast and secure. Dynamic pages are rendered on-demand by a Node.js server, which allows you to use data from any source and handle user interactions. You can also use incremental static regeneration to update static pages without rebuilding your entire application.
|
||||
|
||||
|
||||
However, one of the challenges of using Next.js is that it requires you to rebuild your application every time you want to change something in your code. This can be time-consuming and risky, especially if you want to test new features in production or perform gradual rollouts. Therefore, you need a way to toggle features on and off dynamically without redeploying your code. This is where feature flags come in.
|
||||
|
||||
|
||||
Unleash is an open-source, easy-to-use feature management platform that supports Next.js and other frameworks. With Unleash, you can create and manage feature flags from a user-friendly dashboard and use them in your code with a simple API. Unleash also provides advanced features such as segmentation, strategies, and integrations.
|
||||
|
||||
|
||||
In this tutorial, you will learn how to use feature flags in a Next.js application that displays random activities to users using Unleash. We will use the `@unleash/nextjs` package, which provides easy integration of Unleash feature flags in a Next.js application.
|
||||
Note: If you only need a very simple setup for feature flags in your Next.js application, like toggling a feature on and off for all users, use the [Vercel Edge Config](https://vercel.com/docs/storage/edge-config/get-started). You can avoid making requests to the Unleash API from your application and instead use the edge config to inject the feature flag values into your pages.
|
||||
![Next.js Feature Flag Architecture Diagram](/img/nextjs-feature-flag-architecture-diagram-blog.png)
|
||||
|
||||
|
||||
## Setup Unleash
|
||||
|
||||
|
||||
Before you proceed, ensure you have an Unleash instance running. Run the following commands in the terminal:
|
||||
|
||||
```
|
||||
@ -51,7 +42,6 @@ wget getunleash.io/docker-compose.yml
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
|
||||
This will start Unleash in the background. Once Unleash is running, you can access it at http://localhost:4242.
|
||||
|
||||
```
|
||||
@ -59,20 +49,16 @@ Username: admin
|
||||
Password: unleash4all
|
||||
```
|
||||
|
||||
|
||||
## Create a New Feature
|
||||
|
||||
Create a new feature flag in your Unleash instance named "activity".
|
||||
|
||||
![Create a new feature flag in Unleash](/img/create-new-flag-nextjs.png)
|
||||
|
||||
|
||||
## Integrating Unleash in Nextjs
|
||||
|
||||
|
||||
To get started with Next.js and Unleash, you need to create a Next.js project and add the `@unleash/nextjs` package as a dependency.
|
||||
|
||||
|
||||
You can run the following commands in your terminal to do this:
|
||||
|
||||
```
|
||||
@ -81,50 +67,47 @@ cd activity-app
|
||||
npm install @unleash/nextjs
|
||||
```
|
||||
|
||||
|
||||
To make feature flags available to our Next.js application, we will wrap it with the FlagProvider component from the @unleash/nextjs package. This component will initialize the Unleash SDK and provide access to feature flags throughout our application. We will do this by adding it to our `pages/_app.tsx` file.
|
||||
|
||||
```
|
||||
import type { AppProps } from "next/app"
|
||||
import { FlagProvider } from "@unleash/nextjs/client"
|
||||
```tsx
|
||||
import type { AppProps } from "next/app";
|
||||
import { FlagProvider } from "@unleash/nextjs/client";
|
||||
|
||||
export default function App({ Component, pageProps }: AppProps) {
|
||||
return (
|
||||
<FlagProvider>
|
||||
<Component {...pageProps} />
|
||||
</FlagProvider>
|
||||
)
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Next, we will use the Bored API to retrieve a random activity and then use the `useFlag` feature to determine whether the activity is displayed or not.
|
||||
|
||||
|
||||
```
|
||||
import { useEffect, useState } from "react"
|
||||
import { useFlag } from "@unleash/nextjs/client"
|
||||
```tsx
|
||||
import { useEffect, useState } from "react";
|
||||
import { useFlag } from "@unleash/nextjs/client";
|
||||
|
||||
const Activity = () => {
|
||||
const [activityData, setActivityData] = useState({})
|
||||
const [activityData, setActivityData] = useState({});
|
||||
|
||||
const showActivity = useFlag("activity")
|
||||
const showActivity = useFlag("activity");
|
||||
|
||||
useEffect(() => {
|
||||
const fetchActivity = async () => {
|
||||
try {
|
||||
const response = await fetch("https://www.boredapi.com/api/activity/")
|
||||
const data = await response.json()
|
||||
setActivityData(data)
|
||||
const response = await fetch("https://www.boredapi.com/api/activity/");
|
||||
const data = await response.json();
|
||||
setActivityData(data);
|
||||
} catch (error) {
|
||||
console.error("Error fetching activity:", error)
|
||||
console.error("Error fetching activity:", error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (showActivity) {
|
||||
fetchActivity()
|
||||
fetchActivity();
|
||||
}
|
||||
}, [showActivity])
|
||||
}, [showActivity]);
|
||||
|
||||
return (
|
||||
<div className="bg-gray-100 min-h-screen flex items-center justify-center">
|
||||
@ -143,35 +126,28 @@ const Activity = () => {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default Activity
|
||||
export default Activity;
|
||||
```
|
||||
|
||||
|
||||
Our feature flag can now be used to control whether or not activity is displayed. If we toggle on the gradual roll out:
|
||||
|
||||
![Gradual Rollout](/img/gradual-rollout-nextjs.png)
|
||||
|
||||
|
||||
The activity is displayed:
|
||||
|
||||
![Activity Successful](/img/activity-success-nextjs.png)
|
||||
|
||||
|
||||
If we toggle it off:
|
||||
|
||||
![Toggle Off](/img/gradual-rollout-nextjs-1.png)
|
||||
|
||||
|
||||
No activity is displayed:
|
||||
|
||||
![Activity Successful](/img/activity-success-nextjs-1.png)
|
||||
|
||||
|
||||
|
||||
|
||||
To configure access to Unleash beyond localhost development, follow these steps:
|
||||
|
||||
- Self-host Unleash or run an instance on [Unleash Cloud](https://www.getunleash.io/pricing).
|
||||
@ -180,8 +156,8 @@ To configure access to Unleash beyond localhost development, follow these steps:
|
||||
|
||||
- Store the API key in your Vercel Project Environment Variable, which secures it and makes it accessible in your code.
|
||||
|
||||
|
||||
## Conclusion
|
||||
|
||||
Feature flags are a powerful tool for managing features in web applications. This tutorial showed us how to use feature flags with Next.js and Unleash. We have seen how to create and manage feature flags in the Unleash dashboard, and how to use them in our Next.js code with the @unleash/nextjs library. We have also seen how to test our feature flags by toggling them on and off in the Unleash dashboard.
|
||||
|
||||
Unleash is a powerful and easy-to-use feature management platform that can help you deliver faster and safer web applications with Next.js and other frameworks. If you are not already using feature flags in your Next.js applications, I encourage you to try Unleash and see how it can improve your development workflow.
|
||||
|
@ -28,16 +28,13 @@
|
||||
"@mdx-js/react": "1.6.22",
|
||||
"@svgr/webpack": "8.1.0",
|
||||
"browserslist": "^4.16.5",
|
||||
"clsx": "1.2.1",
|
||||
"docusaurus-plugin-openapi-docs": "2.0.0-beta.3",
|
||||
"docusaurus-plugin-remote-content": "^3.1.0",
|
||||
"docusaurus-theme-openapi-docs": "2.0.0-beta.2",
|
||||
"file-loader": "6.2.0",
|
||||
"immer": "^9.0.6",
|
||||
"plugin-image-zoom": "flexanalytics/plugin-image-zoom",
|
||||
"prism-svelte": "^0.5.0",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"unleash-proxy-client": "2.5.0",
|
||||
"url-loader": "4.1.1"
|
||||
},
|
||||
"resolutions": {
|
||||
@ -47,18 +44,19 @@
|
||||
"glob-parent": "^6.0.0",
|
||||
"browserslist": "^4.16.5",
|
||||
"set-value": "^4.0.1",
|
||||
"immer": "^9.0.6",
|
||||
"ansi-regex": "^5.0.1",
|
||||
"nth-check": "^2.0.1",
|
||||
"shelljs": "^0.8.5",
|
||||
"trim-newlines": "^5.0.0",
|
||||
"minimatch": "^5.0.0",
|
||||
"decode-uri-component": "^0.4.0",
|
||||
"qs": "^6.9.7",
|
||||
"semver": "^7.5.3"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [">0.5%", "not dead", "not op_mini all"],
|
||||
"production": [
|
||||
">0.5%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
|
22
website/src/theme/prism-include-languages.js
Normal file
22
website/src/theme/prism-include-languages.js
Normal file
@ -0,0 +1,22 @@
|
||||
import siteConfig from '@generated/docusaurus.config';
|
||||
export default function prismIncludeLanguages(PrismObject) {
|
||||
const {
|
||||
themeConfig: { prism },
|
||||
} = siteConfig;
|
||||
const { additionalLanguages } = prism;
|
||||
// Prism components work on the Prism instance on the window, while prism-
|
||||
// react-renderer uses its own Prism instance. We temporarily mount the
|
||||
// instance onto window, import components to enhance it, then remove it to
|
||||
// avoid polluting global namespace.
|
||||
// You can mutate PrismObject: registering plugins, deleting languages... As
|
||||
// long as you don't re-assign it
|
||||
globalThis.Prism = PrismObject;
|
||||
additionalLanguages.forEach((lang) => {
|
||||
// eslint-disable-next-line global-require, import/no-dynamic-require
|
||||
require(`prismjs/components/prism-${lang}`);
|
||||
});
|
||||
|
||||
require('prism-svelte');
|
||||
|
||||
delete globalThis.Prism;
|
||||
}
|
@ -3266,9 +3266,9 @@
|
||||
integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==
|
||||
|
||||
"@sindresorhus/is@^5.2.0":
|
||||
version "5.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-5.4.1.tgz#c4383ce702fb90531c3d310506bab89e70427c53"
|
||||
integrity sha512-axlrvsHlHlFmKKMEg4VyvMzFr93JWJj4eIfXY1STVuO2fsImCa7ncaiG5gC8HKOX590AW5RtRsC41/B+OfrSqw==
|
||||
version "5.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-5.6.0.tgz#41dd6093d34652cddb5d5bdeee04eafc33826668"
|
||||
integrity sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==
|
||||
|
||||
"@slorber/static-site-generator-webpack-plugin@^4.0.7":
|
||||
version "4.0.7"
|
||||
@ -3615,10 +3615,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35"
|
||||
integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==
|
||||
|
||||
"@types/http-cache-semantics@^4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812"
|
||||
integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==
|
||||
"@types/http-cache-semantics@^4.0.2":
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4"
|
||||
integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==
|
||||
|
||||
"@types/http-proxy@^1.17.8":
|
||||
version "1.17.9"
|
||||
@ -4563,14 +4563,14 @@ cacheable-lookup@^7.0.0:
|
||||
integrity sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==
|
||||
|
||||
cacheable-request@^10.2.8:
|
||||
version "10.2.10"
|
||||
resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-10.2.10.tgz#1785984a9a4ddec8dd01792232cca474be49a8af"
|
||||
integrity sha512-v6WB+Epm/qO4Hdlio/sfUn69r5Shgh39SsE9DSd4bIezP0mblOlObI+I0kUEM7J0JFc+I7pSeMeYaOYtX1N/VQ==
|
||||
version "10.2.14"
|
||||
resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-10.2.14.tgz#eb915b665fda41b79652782df3f553449c406b9d"
|
||||
integrity sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==
|
||||
dependencies:
|
||||
"@types/http-cache-semantics" "^4.0.1"
|
||||
"@types/http-cache-semantics" "^4.0.2"
|
||||
get-stream "^6.0.1"
|
||||
http-cache-semantics "^4.1.1"
|
||||
keyv "^4.5.2"
|
||||
keyv "^4.5.3"
|
||||
mimic-response "^4.0.0"
|
||||
normalize-url "^8.0.0"
|
||||
responselike "^3.0.0"
|
||||
@ -4815,7 +4815,7 @@ clone-deep@^4.0.1:
|
||||
kind-of "^6.0.2"
|
||||
shallow-clone "^3.0.0"
|
||||
|
||||
clsx@1.2.1, clsx@^1.1.1, clsx@^1.2.1:
|
||||
clsx@^1.1.1, clsx@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
|
||||
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
|
||||
@ -6419,7 +6419,7 @@ feed@^4.2.2:
|
||||
dependencies:
|
||||
xml-js "^1.6.11"
|
||||
|
||||
file-loader@6.2.0, file-loader@^6.2.0:
|
||||
file-loader@^6.2.0:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d"
|
||||
integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==
|
||||
@ -7244,9 +7244,9 @@ http2-client@^1.2.5:
|
||||
integrity sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==
|
||||
|
||||
http2-wrapper@^2.1.10:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.2.0.tgz#b80ad199d216b7d3680195077bd7b9060fa9d7f3"
|
||||
integrity sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.2.1.tgz#310968153dcdedb160d8b72114363ef5fce1f64a"
|
||||
integrity sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==
|
||||
dependencies:
|
||||
quick-lru "^5.1.1"
|
||||
resolve-alpn "^1.2.0"
|
||||
@ -7297,7 +7297,7 @@ image-size@^1.0.1:
|
||||
dependencies:
|
||||
queue "6.0.2"
|
||||
|
||||
immer@^9.0.16, immer@^9.0.6, immer@^9.0.7:
|
||||
immer@^9.0.16, immer@^9.0.7:
|
||||
version "9.0.21"
|
||||
resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176"
|
||||
integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==
|
||||
@ -7790,10 +7790,10 @@ jsonfile@^6.0.1:
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
keyv@^4.5.2:
|
||||
version "4.5.2"
|
||||
resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.2.tgz#0e310ce73bf7851ec702f2eaf46ec4e3805cce56"
|
||||
integrity sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==
|
||||
keyv@^4.5.3:
|
||||
version "4.5.4"
|
||||
resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93"
|
||||
integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==
|
||||
dependencies:
|
||||
json-buffer "3.0.1"
|
||||
|
||||
@ -8638,9 +8638,9 @@ normalize-url@^6.0.1:
|
||||
integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
|
||||
|
||||
normalize-url@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-8.0.0.tgz#593dbd284f743e8dcf6a5ddf8fadff149c82701a"
|
||||
integrity sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==
|
||||
version "8.0.1"
|
||||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-8.0.1.tgz#9b7d96af9836577c58f5883e939365fa15623a4a"
|
||||
integrity sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==
|
||||
|
||||
npm-run-path@^4.0.1:
|
||||
version "4.0.1"
|
||||
@ -11018,11 +11018,6 @@ timers-browserify@^2.0.12:
|
||||
dependencies:
|
||||
setimmediate "^1.0.4"
|
||||
|
||||
tiny-emitter@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
|
||||
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
|
||||
|
||||
tiny-invariant@^1.0.2:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642"
|
||||
@ -11065,11 +11060,6 @@ trim-lines@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-3.0.1.tgz#d802e332a07df861c48802c04321017b1bd87338"
|
||||
integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==
|
||||
|
||||
trim-newlines@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-5.0.0.tgz#fbe350dc9d5fe15e80793b86c09bc7436a3da383"
|
||||
integrity sha512-kstfs+hgwmdsOadN3KgA+C68wPJwnZq4DN6WMDCvZapDWEF34W2TyPKN2v2+BJnZgIz5QOfxFeldLyYvdgRAwg==
|
||||
|
||||
trim-trailing-lines@^1.0.0:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0"
|
||||
@ -11336,14 +11326,6 @@ universalify@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
|
||||
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
|
||||
|
||||
unleash-proxy-client@2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/unleash-proxy-client/-/unleash-proxy-client-2.5.0.tgz#0f4f34285bc3223023ca2cf3ef9dabd2132eea9f"
|
||||
integrity sha512-GWYLcQDW2UVhqAVwZX7jNzD6Lp96UJXEi66r9MiDd/C3Xw7rbTdFziNJAhEZpLNqR7j75+TfZaEYMCMy/k778g==
|
||||
dependencies:
|
||||
tiny-emitter "^2.1.0"
|
||||
uuid "^8.3.2"
|
||||
|
||||
unpipe@1.0.0, unpipe@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
||||
|
Loading…
Reference in New Issue
Block a user