mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
feat: Sdk snippets in test connection phase (#8082)
This commit is contained in:
parent
5c4d0bf99b
commit
ff31013c6d
@ -8,8 +8,15 @@ import {
|
|||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { GenerateApiKey } from './GenerateApiKey';
|
import { GenerateApiKey } from './GenerateApiKey';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { type Sdk, SelectSdk } from './SelectSdk';
|
import { SelectSdk } from './SelectSdk';
|
||||||
import { GenrateApiKeyConcepts, SelectSdkConcepts } from './UnleashConcepts';
|
import {
|
||||||
|
ConceptsDefinitionsWrapper,
|
||||||
|
GenrateApiKeyConcepts,
|
||||||
|
SelectSdkConcepts,
|
||||||
|
} from './UnleashConcepts';
|
||||||
|
import { TestSdkConnection } from './TestSdkConnection';
|
||||||
|
|
||||||
|
import type { Sdk } from './sharedTypes';
|
||||||
|
|
||||||
interface IConnectSDKDialogProps {
|
interface IConnectSDKDialogProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@ -107,7 +114,9 @@ export const ConnectSdkDialog = ({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
{isTestConnectionStage ? <div>Last stage</div> : null}
|
{isTestConnectionStage ? (
|
||||||
|
<TestSdkConnection sdk={sdk} apiKey={apiKey} />
|
||||||
|
) : null}
|
||||||
|
|
||||||
{stage === 'generate-api-key' ? (
|
{stage === 'generate-api-key' ? (
|
||||||
<Navigation>
|
<Navigation>
|
||||||
@ -163,6 +172,9 @@ export const ConnectSdkDialog = ({
|
|||||||
{isLargeScreen && isGenerateApiKeyStage ? (
|
{isLargeScreen && isGenerateApiKeyStage ? (
|
||||||
<GenrateApiKeyConcepts />
|
<GenrateApiKeyConcepts />
|
||||||
) : null}
|
) : null}
|
||||||
|
{isLargeScreen && isTestConnectionStage ? (
|
||||||
|
<ConceptsDefinitionsWrapper />
|
||||||
|
) : null}
|
||||||
</Box>
|
</Box>
|
||||||
</StyledDialog>
|
</StyledDialog>
|
||||||
);
|
);
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { useProjectApiTokens } from '../../hooks/api/getters/useProjectApiTokens/useProjectApiTokens';
|
import { useProjectApiTokens } from 'hooks/api/getters/useProjectApiTokens/useProjectApiTokens';
|
||||||
import useProjectApiTokensApi from '../../hooks/api/actions/useProjectApiTokensApi/useProjectApiTokensApi';
|
import useProjectApiTokensApi from 'hooks/api/actions/useProjectApiTokensApi/useProjectApiTokensApi';
|
||||||
import { parseToken } from './parseToken';
|
import { parseToken } from './parseToken';
|
||||||
import useToast from '../../hooks/useToast';
|
import useToast from 'hooks/useToast';
|
||||||
import { formatUnknownError } from '../../utils/formatUnknownError';
|
import { formatUnknownError } from 'utils/formatUnknownError';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
@ -15,6 +15,7 @@ import { SingleSelectConfigButton } from '../common/DialogFormTemplate/ConfigBut
|
|||||||
import EnvironmentsIcon from '@mui/icons-material/CloudCircle';
|
import EnvironmentsIcon from '@mui/icons-material/CloudCircle';
|
||||||
import { ArcherContainer, ArcherElement } from 'react-archer';
|
import { ArcherContainer, ArcherElement } from 'react-archer';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
import { SectionHeader } from './SharedComponents';
|
||||||
|
|
||||||
const ChooseEnvironment = ({
|
const ChooseEnvironment = ({
|
||||||
environments,
|
environments,
|
||||||
@ -79,12 +80,6 @@ const TokenExplanationBox = styled(Box)(({ theme }) => ({
|
|||||||
flexWrap: 'wrap',
|
flexWrap: 'wrap',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const SectionHeader = styled('div')(({ theme }) => ({
|
|
||||||
fontWeight: theme.typography.fontWeightBold,
|
|
||||||
marginBottom: theme.spacing(1),
|
|
||||||
fontSize: theme.typography.body1.fontSize,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const SectionDescription = styled('p')(({ theme }) => ({
|
const SectionDescription = styled('p')(({ theme }) => ({
|
||||||
color: theme.palette.text.secondary,
|
color: theme.palette.text.secondary,
|
||||||
fontSize: theme.typography.body2.fontSize,
|
fontSize: theme.typography.body2.fontSize,
|
||||||
|
@ -16,6 +16,8 @@ import rust from 'assets/icons/sdks/Logo-rust.svg';
|
|||||||
import svelte from 'assets/icons/sdks/Logo-svelte.svg';
|
import svelte from 'assets/icons/sdks/Logo-svelte.svg';
|
||||||
import vue from 'assets/icons/sdks/Logo-vue.svg';
|
import vue from 'assets/icons/sdks/Logo-vue.svg';
|
||||||
import { formatAssetPath } from 'utils/formatPath';
|
import { formatAssetPath } from 'utils/formatPath';
|
||||||
|
import { SectionHeader } from './SharedComponents';
|
||||||
|
import type { ClientSdkName, Sdk, ServerSdkName } from './sharedTypes';
|
||||||
|
|
||||||
const SpacedContainer = styled('div')(({ theme }) => ({
|
const SpacedContainer = styled('div')(({ theme }) => ({
|
||||||
padding: theme.spacing(5, 8, 8, 8),
|
padding: theme.spacing(5, 8, 8, 8),
|
||||||
@ -24,12 +26,6 @@ const SpacedContainer = styled('div')(({ theme }) => ({
|
|||||||
gap: theme.spacing(3),
|
gap: theme.spacing(3),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const PrimarySectionHeader = styled('div')(({ theme }) => ({
|
|
||||||
fontWeight: theme.typography.fontWeightBold,
|
|
||||||
marginBottom: theme.spacing(1),
|
|
||||||
fontSize: theme.typography.body1.fontSize,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const SecondarySectionHeader = styled('div')(({ theme }) => ({
|
const SecondarySectionHeader = styled('div')(({ theme }) => ({
|
||||||
marginTop: theme.spacing(4),
|
marginTop: theme.spacing(4),
|
||||||
marginBottom: theme.spacing(2),
|
marginBottom: theme.spacing(2),
|
||||||
@ -71,7 +67,7 @@ const StyledAvatar = styled(Avatar)(({ theme }) => ({
|
|||||||
boxShadow: theme.shadows[2],
|
boxShadow: theme.shadows[2],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const serverSdks = [
|
const serverSdks: { name: ServerSdkName; icon: string }[] = [
|
||||||
{ name: 'Node', icon: node },
|
{ name: 'Node', icon: node },
|
||||||
{ name: 'Golang', icon: go },
|
{ name: 'Golang', icon: go },
|
||||||
{ name: 'Ruby', icon: ruby },
|
{ name: 'Ruby', icon: ruby },
|
||||||
@ -82,7 +78,7 @@ const serverSdks = [
|
|||||||
{ name: 'Python', icon: python },
|
{ name: 'Python', icon: python },
|
||||||
];
|
];
|
||||||
|
|
||||||
const clientSdks = [
|
const clientSdks: { name: ClientSdkName; icon: string }[] = [
|
||||||
{ name: 'Javascript', icon: javascript },
|
{ name: 'Javascript', icon: javascript },
|
||||||
{ name: 'React', icon: react },
|
{ name: 'React', icon: react },
|
||||||
{ name: 'Vue', icon: vue },
|
{ name: 'Vue', icon: vue },
|
||||||
@ -92,8 +88,6 @@ const clientSdks = [
|
|||||||
{ name: 'Flutter', icon: flutter },
|
{ name: 'Flutter', icon: flutter },
|
||||||
];
|
];
|
||||||
|
|
||||||
type SdkType = 'client' | 'frontend';
|
|
||||||
export type Sdk = { name: string; type: SdkType };
|
|
||||||
interface ISelectSdkProps {
|
interface ISelectSdkProps {
|
||||||
onSelect: (sdk: Sdk) => void;
|
onSelect: (sdk: Sdk) => void;
|
||||||
}
|
}
|
||||||
@ -102,7 +96,7 @@ export const SelectSdk: FC<ISelectSdkProps> = ({ onSelect }) => {
|
|||||||
<SpacedContainer>
|
<SpacedContainer>
|
||||||
<Typography variant='h2'>Connect an SDK to Unleash</Typography>
|
<Typography variant='h2'>Connect an SDK to Unleash</Typography>
|
||||||
<Box sx={{ mt: 4 }}>
|
<Box sx={{ mt: 4 }}>
|
||||||
<PrimarySectionHeader>Select SDK</PrimarySectionHeader>
|
<SectionHeader>Select SDK</SectionHeader>
|
||||||
<SecondarySectionHeader>
|
<SecondarySectionHeader>
|
||||||
Server side SDKs
|
Server side SDKs
|
||||||
</SecondarySectionHeader>
|
</SecondarySectionHeader>
|
||||||
@ -155,5 +149,3 @@ export const SelectSdk: FC<ISelectSdkProps> = ({ onSelect }) => {
|
|||||||
</SpacedContainer>
|
</SpacedContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SelectSdkConcepts = () => {};
|
|
||||||
|
7
frontend/src/component/onboarding/SharedComponents.tsx
Normal file
7
frontend/src/component/onboarding/SharedComponents.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { styled } from '@mui/material';
|
||||||
|
|
||||||
|
export const SectionHeader = styled('div')(({ theme }) => ({
|
||||||
|
fontWeight: theme.typography.fontWeightBold,
|
||||||
|
marginBottom: theme.spacing(1),
|
||||||
|
fontSize: theme.typography.body1.fontSize,
|
||||||
|
}));
|
60
frontend/src/component/onboarding/TestSdkConnection.tsx
Normal file
60
frontend/src/component/onboarding/TestSdkConnection.tsx
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import type { FC } from 'react';
|
||||||
|
import { Box, styled, Typography } from '@mui/material';
|
||||||
|
import { SectionHeader } from './SharedComponents';
|
||||||
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
|
import type { Sdk } from './sharedTypes';
|
||||||
|
import { codeSnippets, installCommands } from './sdkSnippets';
|
||||||
|
|
||||||
|
const SpacedContainer = styled('div')(({ theme }) => ({
|
||||||
|
padding: theme.spacing(5, 8, 8, 8),
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: theme.spacing(3),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledCodeBlock = styled('pre')(({ theme }) => ({
|
||||||
|
backgroundColor: theme.palette.background.elevation1,
|
||||||
|
padding: theme.spacing(2),
|
||||||
|
borderRadius: theme.shape.borderRadius,
|
||||||
|
overflow: 'auto',
|
||||||
|
fontSize: theme.typography.body2.fontSize,
|
||||||
|
wordBreak: 'break-all',
|
||||||
|
whiteSpace: 'pre-wrap',
|
||||||
|
}));
|
||||||
|
|
||||||
|
interface ITestSdkConnectionProps {
|
||||||
|
sdk: Sdk;
|
||||||
|
apiKey: string;
|
||||||
|
}
|
||||||
|
export const TestSdkConnection: FC<ITestSdkConnectionProps> = ({
|
||||||
|
sdk,
|
||||||
|
apiKey,
|
||||||
|
}) => {
|
||||||
|
const { uiConfig } = useUiConfig();
|
||||||
|
|
||||||
|
const clientApiUrl = `${uiConfig.unleashUrl}/api/`;
|
||||||
|
const frontendApiUrl = `${uiConfig.unleashUrl}/api/frontend/`;
|
||||||
|
const apiUrl = sdk.type === 'client' ? clientApiUrl : frontendApiUrl;
|
||||||
|
const codeSnippet =
|
||||||
|
codeSnippets[sdk.name] || `No snippet found for the ${sdk.name} SDK`;
|
||||||
|
const installCommand =
|
||||||
|
installCommands[sdk.name] ||
|
||||||
|
`No install command found for the ${sdk.name} SDK`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SpacedContainer>
|
||||||
|
<Typography variant='h2'>Connect an SDK to Unleash</Typography>
|
||||||
|
<Box sx={{ mt: 4 }}>
|
||||||
|
<SectionHeader>Setup the SDK</SectionHeader>
|
||||||
|
<p>1. Install the SDK</p>
|
||||||
|
<StyledCodeBlock>{installCommand}</StyledCodeBlock>
|
||||||
|
<p>2. Initialize the SDK</p>
|
||||||
|
<StyledCodeBlock>
|
||||||
|
{codeSnippet
|
||||||
|
.replace('<YOUR_API_TOKEN>', apiKey)
|
||||||
|
.replace('<YOUR_API_URL>', apiUrl)}
|
||||||
|
</StyledCodeBlock>
|
||||||
|
</Box>
|
||||||
|
</SpacedContainer>
|
||||||
|
);
|
||||||
|
};
|
@ -3,7 +3,7 @@ import { ProjectIcon } from '../common/ProjectIcon/ProjectIcon';
|
|||||||
import EnvironmentsIcon from '@mui/icons-material/CloudCircle';
|
import EnvironmentsIcon from '@mui/icons-material/CloudCircle';
|
||||||
import CodeIcon from '@mui/icons-material/Code';
|
import CodeIcon from '@mui/icons-material/Code';
|
||||||
|
|
||||||
const ConceptsDefinitionsWrapper = styled('div')(({ theme }) => ({
|
export const ConceptsDefinitionsWrapper = styled('div')(({ theme }) => ({
|
||||||
backgroundColor: theme.palette.background.sidebar,
|
backgroundColor: theme.palette.background.sidebar,
|
||||||
padding: theme.spacing(12, 6, 6, 6),
|
padding: theme.spacing(12, 6, 6, 6),
|
||||||
flex: 0,
|
flex: 0,
|
||||||
|
183
frontend/src/component/onboarding/sdkSnippets.ts
Normal file
183
frontend/src/component/onboarding/sdkSnippets.ts
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
import type { SdkName } from './sharedTypes';
|
||||||
|
|
||||||
|
export const installCommands: Record<SdkName, string> = {
|
||||||
|
Node: ' npm install unleash-client',
|
||||||
|
Golang: 'go get github.com/Unleash/unleash-client-go/v3',
|
||||||
|
Ruby: 'gem install unleash',
|
||||||
|
PHP: 'composer require unleash/client',
|
||||||
|
Rust: 'cargo add unleash-client',
|
||||||
|
DotNet: `dotnet add package unleash.client
|
||||||
|
// If you do not have a json library in your project:
|
||||||
|
dotnet add package Newtonsoft.Json`,
|
||||||
|
Java: `<dependency>
|
||||||
|
<groupId>io.getunleash</groupId>
|
||||||
|
<artifactId>unleash-client-java</artifactId>
|
||||||
|
<version>Latest version here</version>
|
||||||
|
</dependency>`,
|
||||||
|
Python: 'pip install UnleashClient',
|
||||||
|
Javascript: 'npm install unleash-proxy-client',
|
||||||
|
React: 'npm install @unleash/proxy-client-react unleash-proxy-client',
|
||||||
|
Vue: 'npm install @unleash/proxy-client-vue',
|
||||||
|
Svelte: 'npm install @unleash/proxy-client-svelte',
|
||||||
|
Swift: 'https://github.com/Unleash/unleash-proxy-client-swift',
|
||||||
|
Android:
|
||||||
|
'implementation("io.getunleash:unleash-android:${unleash.sdk.version}")',
|
||||||
|
Flutter: 'flutter pub add unleash_proxy_client_flutter',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const codeSnippets: Record<SdkName, string> = {
|
||||||
|
Node: `import { initialize } from 'unleash-client';
|
||||||
|
|
||||||
|
const unleash = initialize({
|
||||||
|
url: '<YOUR_API_URL>',
|
||||||
|
appName: 'unleash-onboarding-node',
|
||||||
|
customHeaders: { Authorization: '<YOUR_API_TOKEN>' },
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
Golang: `import (
|
||||||
|
"github.com/Unleash/unleash-client-go/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
unleash.Initialize(
|
||||||
|
unleash.WithListener(&unleash.DebugListener{}),
|
||||||
|
unleash.WithAppName("unleash-onboarding-golang"),
|
||||||
|
unleash.WithUrl("<YOUR_API_URL>"),
|
||||||
|
unleash.WithCustomHeaders(http.Header{"Authorization": {"<YOUR_API_TOKEN>"}}),
|
||||||
|
)
|
||||||
|
}`,
|
||||||
|
Ruby: `Unleash.configure do |config|
|
||||||
|
config.app_name = 'unleash-onboarding-ruby'
|
||||||
|
config.url = '<YOUR_API_URL>'
|
||||||
|
config.custom_http_headers = {'Authorization': '<YOUR_API_TOKEN>'}
|
||||||
|
end`,
|
||||||
|
PHP: `<?php
|
||||||
|
|
||||||
|
use Unleash\\Client\\UnleashBuilder;
|
||||||
|
|
||||||
|
$unleash = UnleashBuilder::create()
|
||||||
|
->withAppName('unleash-onboarding-php')
|
||||||
|
->withAppUrl('<YOUR_API_URL>')
|
||||||
|
->withHeader('Authorization', '<YOUR_API_TOKEN>')
|
||||||
|
->withInstanceId('unleash-onboarding-instance')
|
||||||
|
->build();`,
|
||||||
|
Rust: `let client = client::ClientBuilder::default()
|
||||||
|
.interval(500)
|
||||||
|
.into_client::<UserFeatures, reqwest::Client>(
|
||||||
|
"<YOUR_API_URL>",
|
||||||
|
"unleash-onboarding-rust",
|
||||||
|
"unleash-onboarding-instance",
|
||||||
|
"<YOUR_API_TOKEN>",
|
||||||
|
)?;
|
||||||
|
client.register().await?;`,
|
||||||
|
DotNet: `using Unleash;
|
||||||
|
var settings = new UnleashSettings()
|
||||||
|
{
|
||||||
|
AppName = "unleash-onboarding-dotnet",
|
||||||
|
UnleashApi = new Uri("<YOUR_API_URL>"),
|
||||||
|
CustomHttpHeaders = new Dictionary<string, string>()
|
||||||
|
{
|
||||||
|
{"Authorization","<YOUR_API_TOKEN>" }
|
||||||
|
}
|
||||||
|
};`,
|
||||||
|
Java: `UnleashConfig config = UnleashConfig.builder()
|
||||||
|
.appName("unleash-onboarding-java")
|
||||||
|
.instanceId("unleash-onboarding-instance")
|
||||||
|
.unleashAPI("<YOUR_API_URL>")
|
||||||
|
.apiKey("<YOUR_API_TOKEN>")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Unleash unleash = new DefaultUnleash(config);`,
|
||||||
|
Python: `from UnleashClient import UnleashClient
|
||||||
|
|
||||||
|
client = UnleashClient(
|
||||||
|
url="<YOUR_API_URL>",
|
||||||
|
app_name="unleash-onboarding-python",
|
||||||
|
custom_headers={'Authorization': '<YOUR_API_TOKEN>"'})
|
||||||
|
|
||||||
|
client.initialize_client()`,
|
||||||
|
Javascript: `import { UnleashClient } from 'unleash-proxy-client';
|
||||||
|
|
||||||
|
const unleash = new UnleashClient({
|
||||||
|
url: '<YOUR_API_URL>',
|
||||||
|
clientKey: '<YOUR_API_TOKEN>',
|
||||||
|
appName: 'unleash-onboarding-javascript',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start the background polling
|
||||||
|
unleash.start();`,
|
||||||
|
React: `import { createRoot } from 'react-dom/client';
|
||||||
|
import { FlagProvider } from '@unleash/proxy-client-react';
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
url: '<YOUR_API_URL>',
|
||||||
|
clientKey: '<YOUR_API_TOKEN>',
|
||||||
|
refreshInterval: 15,
|
||||||
|
appName: 'unleash-onboarding-react',
|
||||||
|
};
|
||||||
|
|
||||||
|
const root = createRoot(document.getElementById('root'));
|
||||||
|
|
||||||
|
root.render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<FlagProvider config={config}>
|
||||||
|
<App />
|
||||||
|
</FlagProvider>
|
||||||
|
</React.StrictMode>
|
||||||
|
);`,
|
||||||
|
Vue: `import { createApp } from 'vue'
|
||||||
|
import { plugin as unleashPlugin } from '@unleash/proxy-client-vue'
|
||||||
|
// import the root component App from a single-file component.
|
||||||
|
import App from './App.vue'
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
url: '<YOUR_API_URL>'',
|
||||||
|
clientKey: '<YOUR_API_TOKEN>',
|
||||||
|
refreshInterval: 15,
|
||||||
|
appName: 'unleash-onboarding-vue',
|
||||||
|
}
|
||||||
|
|
||||||
|
const app = createApp(App)
|
||||||
|
app.use(unleashPlugin, { config })
|
||||||
|
app.mount('#app')`,
|
||||||
|
Svelte: `<script lang="ts">
|
||||||
|
import { FlagProvider } from '@unleash/proxy-client-svelte';
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
url: '<YOUR_API_URL>',
|
||||||
|
clientKey: '<YOUR_API_TOKEN>',
|
||||||
|
refreshInterval: 15,
|
||||||
|
appName: 'unleash-onboarding-svelte'
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<FlagProvider {config}>
|
||||||
|
<App />
|
||||||
|
</FlagProvider>`,
|
||||||
|
Swift: `import SwiftUI
|
||||||
|
import UnleashProxyClientSwift
|
||||||
|
|
||||||
|
var unleash = UnleashProxyClientSwift.UnleashClient(
|
||||||
|
unleashUrl: "<YOUR_API_URL>",
|
||||||
|
clientKey: "<YOUR_API_TOKEN>",
|
||||||
|
refreshInterval: 15,
|
||||||
|
appName: "unleash-onboarding-swift",
|
||||||
|
context: [:])
|
||||||
|
|
||||||
|
unleash.start()`,
|
||||||
|
Android: `val unleash = DefaultUnleash(
|
||||||
|
androidContext = applicationContext, // likely a reference to your Android application context
|
||||||
|
unleashConfig = UnleashConfig.newBuilder(appName = "unleash-onboarding-android")
|
||||||
|
.proxyUrl("<YOUR_API_URL>")
|
||||||
|
.clientKey("<YOUR_API_TOKEN>")
|
||||||
|
.pollingStrategy.interval(3000)
|
||||||
|
.metricsStrategy.interval(3000)
|
||||||
|
.build()
|
||||||
|
)`,
|
||||||
|
Flutter: `import 'package:unleash_proxy_client_flutter/unleash_proxy_client_flutter.dart';
|
||||||
|
|
||||||
|
final unleash = UnleashClient(
|
||||||
|
url: Uri.parse('<YOUR_API_URL>'),
|
||||||
|
clientKey: '<YOUR_API_TOKEN>',
|
||||||
|
appName: 'unleash-onboarding-flutter');`,
|
||||||
|
};
|
20
frontend/src/component/onboarding/sharedTypes.ts
Normal file
20
frontend/src/component/onboarding/sharedTypes.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
export type SdkType = 'client' | 'frontend';
|
||||||
|
export type Sdk = { name: SdkName; type: SdkType };
|
||||||
|
export type ServerSdkName =
|
||||||
|
| 'Node'
|
||||||
|
| 'Golang'
|
||||||
|
| 'Ruby'
|
||||||
|
| 'PHP'
|
||||||
|
| 'Rust'
|
||||||
|
| 'DotNet'
|
||||||
|
| 'Java'
|
||||||
|
| 'Python';
|
||||||
|
export type ClientSdkName =
|
||||||
|
| 'Javascript'
|
||||||
|
| 'React'
|
||||||
|
| 'Vue'
|
||||||
|
| 'Svelte'
|
||||||
|
| 'Swift'
|
||||||
|
| 'Android'
|
||||||
|
| 'Flutter';
|
||||||
|
export type SdkName = ServerSdkName | ClientSdkName;
|
Loading…
Reference in New Issue
Block a user