mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: generate an OpenAPI client (2) (#875)
* feat: add a script that generates an OpenAPI client * feat: generate an OpenAPI client * feat: use the generated OpenAPI client * refactor: add an OpenAPI section to the readme * refactor: fix missing interface prefixes * refactor: regenerate OpenAPI client
This commit is contained in:
		
							parent
							
								
									f6e42f99f9
								
							
						
					
					
						commit
						8f1900f32b
					
				| @ -1,2 +1,3 @@ | ||||
| .github/* | ||||
| /src/openapi | ||||
| CHANGELOG.md | ||||
| .github/* | ||||
| @ -23,10 +23,10 @@ yarn install | ||||
| yarn run start:heroku | ||||
| ``` | ||||
| 
 | ||||
| ## Running end-to-end Tests | ||||
| 
 | ||||
| We have a set of Cypress tests that run on the build before a PR can be merged so it's important that you check these yourself before submitting a PR. | ||||
| ## Running end-to-end tests | ||||
| 
 | ||||
| We have a set of Cypress tests that run on the build before a PR can be merged | ||||
| so it's important that you check these yourself before submitting a PR. | ||||
| On the server the tests will run against the deployed Heroku app so this is what you probably want to test against: | ||||
| 
 | ||||
| ``` | ||||
| @ -39,15 +39,30 @@ In a different shell, you can run the tests themselves: | ||||
| yarn run e2e:heroku | ||||
| ``` | ||||
| 
 | ||||
| If you need to test against patches against a local server instance, you'll need to run that, and then run the end to end tests using: | ||||
| If you need to test against patches against a local server instance, | ||||
| you'll need to run that, and then run the end to end tests using: | ||||
| 
 | ||||
| ``` | ||||
| yarn run e2e | ||||
| ``` | ||||
| 
 | ||||
| You may also need to test that a feature works against the enterprise version of unleash. Assuming the Heroku instance is still running, this can be done by: | ||||
| You may also need to test that a feature works against the enterprise version of unleash. | ||||
| Assuming the Heroku instance is still running, this can be done by: | ||||
| 
 | ||||
| ``` | ||||
| yarn run start:enterprise | ||||
| yarn run e2e | ||||
| ``` | ||||
| 
 | ||||
| ## Generating the OpenAPI client | ||||
| 
 | ||||
| The frontend uses an OpenAPI client generated from the backend's OpenAPI spec. | ||||
| Whenever there are changes to the backend API, the client should be regenerated: | ||||
| 
 | ||||
| ``` | ||||
| ./scripts/generate-openapi.sh | ||||
| ``` | ||||
| 
 | ||||
| This script assumes that you have a running instance of the enterprise backend at `http://localhost:4242`. | ||||
| The new OpenAPI client will be generated from the runtime schema of this instance. | ||||
| The target URL can be changed by setting the `UNLEASH_OPENAPI_URL` env var. | ||||
|  | ||||
| @ -40,6 +40,7 @@ | ||||
|     "@material-ui/core": "4.12.4", | ||||
|     "@material-ui/icons": "4.11.3", | ||||
|     "@material-ui/lab": "4.0.0-alpha.61", | ||||
|     "@openapitools/openapi-generator-cli": "^2.4.26", | ||||
|     "@testing-library/dom": "8.12.0", | ||||
|     "@testing-library/jest-dom": "5.16.3", | ||||
|     "@testing-library/react": "12.1.5", | ||||
|  | ||||
							
								
								
									
										24
									
								
								frontend/scripts/generate-openapi.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										24
									
								
								frontend/scripts/generate-openapi.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,24 @@ | ||||
| #!/bin/sh | ||||
| 
 | ||||
| # Generate OpenAPI bindings for the Unleash API. | ||||
| # https://openapi-generator.tech/docs/generators/typescript-fetch | ||||
| 
 | ||||
| set -feux | ||||
| cd "$(dirname "$0")" | ||||
| 
 | ||||
| # URL to the generated open API spec. | ||||
| # Set the UNLEASH_OPENAPI_URL environment variable to override. | ||||
| UNLEASH_OPENAPI_URL="${UNLEASH_OPENAPI_URL:-http://localhost:4242/docs/openapi.json}" | ||||
| 
 | ||||
| rm -rf "../src/openapi" | ||||
| mkdir "../src/openapi" | ||||
| 
 | ||||
| npx @openapitools/openapi-generator-cli generate \ | ||||
|     -g "typescript-fetch" \ | ||||
|     -i "$UNLEASH_OPENAPI_URL" \ | ||||
|     -o "../src/openapi" | ||||
| 
 | ||||
| # Remove unused files. | ||||
| rm  "openapitools.json" | ||||
| rm  "../src/openapi/.openapi-generator-ignore" | ||||
| rm  -r "../src/openapi/.openapi-generator" | ||||
| @ -10,7 +10,7 @@ import { | ||||
|     TextField, | ||||
| } from '@material-ui/core'; | ||||
| 
 | ||||
| interface Props { | ||||
| interface IAutoCreateFormProps { | ||||
|     data?: { | ||||
|         enabled: boolean; | ||||
|         autoCreate: boolean; | ||||
| @ -23,7 +23,7 @@ interface Props { | ||||
| export const AutoCreateForm = ({ | ||||
|     data = { enabled: false, autoCreate: false }, | ||||
|     setValue, | ||||
| }: Props) => { | ||||
| }: IAutoCreateFormProps) => { | ||||
|     const updateAutoCreate = () => { | ||||
|         setValue('autoCreate', !data.autoCreate); | ||||
|     }; | ||||
|  | ||||
| @ -10,7 +10,13 @@ export const ArchiveListContainer = () => { | ||||
|     const { setToastData, setToastApiError } = useToast(); | ||||
|     const { uiConfig } = useUiConfig(); | ||||
|     const { reviveFeature } = useFeatureArchiveApi(); | ||||
|     const { archivedFeatures, loading, refetchArchived } = useFeaturesArchive(); | ||||
| 
 | ||||
|     const { | ||||
|         archivedFeatures = [], | ||||
|         refetchArchived, | ||||
|         loading, | ||||
|     } = useFeaturesArchive(); | ||||
| 
 | ||||
|     const { filtered, filter, setFilter } = useFeaturesFilter(archivedFeatures); | ||||
|     const { sorted, sort, setSort } = useFeaturesSort(filtered); | ||||
| 
 | ||||
|  | ||||
| @ -37,13 +37,13 @@ interface IEnvironmentListItemProps { | ||||
|     moveListItemApi: (dragIndex: number, hoverIndex: number) => Promise<void>; | ||||
| } | ||||
| 
 | ||||
| interface DragItem { | ||||
| interface IDragItem { | ||||
|     index: number; | ||||
|     id: string; | ||||
|     type: string; | ||||
| } | ||||
| 
 | ||||
| interface CollectedProps { | ||||
| interface ICollectedProps { | ||||
|     handlerId: Identifier | null; | ||||
| } | ||||
| 
 | ||||
| @ -69,19 +69,19 @@ const EnvironmentListItem = ({ | ||||
|         }), | ||||
|     }); | ||||
| 
 | ||||
|     const [{ handlerId }, drop] = useDrop<DragItem, unknown, CollectedProps>({ | ||||
|     const [{ handlerId }, drop] = useDrop<IDragItem, unknown, ICollectedProps>({ | ||||
|         accept: ACCEPT_TYPE, | ||||
|         collect(monitor) { | ||||
|             return { | ||||
|                 handlerId: monitor.getHandlerId(), | ||||
|             }; | ||||
|         }, | ||||
|         drop(item: DragItem, monitor: DropTargetMonitor) { | ||||
|         drop(item: IDragItem, monitor: DropTargetMonitor) { | ||||
|             const dragIndex = item.index; | ||||
|             const hoverIndex = index; | ||||
|             moveListItemApi(dragIndex, hoverIndex); | ||||
|         }, | ||||
|         hover(item: DragItem, monitor: DropTargetMonitor) { | ||||
|         hover(item: IDragItem, monitor: DropTargetMonitor) { | ||||
|             if (!ref.current) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
| @ -45,7 +45,6 @@ const CreateFeature = () => { | ||||
|         if (validToggleName) { | ||||
|             const payload = getTogglePayload(); | ||||
|             try { | ||||
|                 // @ts-expect-error
 | ||||
|                 await createFeatureToggle(project, payload); | ||||
|                 history.push(`/projects/${project}/features/${name}`); | ||||
|                 setToastData({ | ||||
|  | ||||
| @ -6,7 +6,7 @@ import { useFeaturesSort } from 'hooks/useFeaturesSort'; | ||||
| 
 | ||||
| export const FeatureToggleListContainer = () => { | ||||
|     const { uiConfig } = useUiConfig(); | ||||
|     const { features, loading } = useFeatures(); | ||||
|     const { features = [], loading } = useFeatures(); | ||||
|     const { filtered, filter, setFilter } = useFeaturesFilter(features); | ||||
|     const { sorted, sort, setSort } = useFeaturesSort(filtered); | ||||
| 
 | ||||
|  | ||||
| @ -2,11 +2,11 @@ import { Tooltip } from '@material-ui/core'; | ||||
| import { useLocationSettings } from 'hooks/useLocationSettings'; | ||||
| import { formatDateYMD, formatDateYMDHMS } from 'utils/formatDate'; | ||||
| 
 | ||||
| interface CreatedAtProps { | ||||
| interface ICreatedAtProps { | ||||
|     time: string; | ||||
| } | ||||
| 
 | ||||
| const CreatedAt = ({ time }: CreatedAtProps) => { | ||||
| const CreatedAt = ({ time }: ICreatedAtProps) => { | ||||
|     const { locationSettings } = useLocationSettings(); | ||||
| 
 | ||||
|     return ( | ||||
|  | ||||
| @ -18,6 +18,10 @@ export const FeatureNotFound = () => { | ||||
|         { name: featureId } | ||||
|     ); | ||||
| 
 | ||||
|     if (!archivedFeatures) { | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     const isArchived = archivedFeatures.some(archivedFeature => { | ||||
|         return archivedFeature.name === featureId; | ||||
|     }); | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| import { IFeatureStrategy } from 'interfaces/strategy'; | ||||
| import FeatureOverviewEnvironmentStrategy from './FeatureOverviewEnvironmentStrategy/FeatureOverviewEnvironmentStrategy'; | ||||
| 
 | ||||
| interface FeatureOverviewEnvironmentStrategiesProps { | ||||
| interface IFeatureOverviewEnvironmentStrategiesProps { | ||||
|     strategies: IFeatureStrategy[]; | ||||
|     environmentName: string; | ||||
| } | ||||
| @ -9,7 +9,7 @@ interface FeatureOverviewEnvironmentStrategiesProps { | ||||
| const FeatureOverviewEnvironmentStrategies = ({ | ||||
|     strategies, | ||||
|     environmentName, | ||||
| }: FeatureOverviewEnvironmentStrategiesProps) => { | ||||
| }: IFeatureOverviewEnvironmentStrategiesProps) => { | ||||
|     return ( | ||||
|         <> | ||||
|             {strategies.map(strategy => ( | ||||
|  | ||||
| @ -46,7 +46,7 @@ function getColor(unit?: string): string { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| interface FeatureStatusProps { | ||||
| interface IFeatureStatusProps { | ||||
|     lastSeenAt?: string; | ||||
|     tooltipPlacement?: TooltipProps['placement']; | ||||
| } | ||||
| @ -54,7 +54,7 @@ interface FeatureStatusProps { | ||||
| const FeatureStatus = ({ | ||||
|     lastSeenAt, | ||||
|     tooltipPlacement, | ||||
| }: FeatureStatusProps) => { | ||||
| }: IFeatureStatusProps) => { | ||||
|     const styles = useStyles(); | ||||
| 
 | ||||
|     const Wrapper = ( | ||||
|  | ||||
| @ -3,11 +3,11 @@ import { Tooltip } from '@material-ui/core'; | ||||
| import { getFeatureTypeIcons } from 'utils/getFeatureTypeIcons'; | ||||
| import useFeatureTypes from 'hooks/api/getters/useFeatureTypes/useFeatureTypes'; | ||||
| 
 | ||||
| interface FeatureTypeProps { | ||||
| interface IFeatureTypeProps { | ||||
|     type: string; | ||||
| } | ||||
| 
 | ||||
| const FeatureStatus = ({ type }: FeatureTypeProps) => { | ||||
| const FeatureStatus = ({ type }: IFeatureTypeProps) => { | ||||
|     const styles = useStyles(); | ||||
|     const { featureTypes } = useFeatureTypes(); | ||||
|     const IconComponent = getFeatureTypeIcons(type); | ||||
|  | ||||
| @ -1,8 +1,8 @@ | ||||
| import { useEffect, useState } from 'react'; | ||||
| import { Redirect, useParams } from 'react-router-dom'; | ||||
| import { useFeatures } from 'hooks/api/getters/useFeatures/useFeatures'; | ||||
| import { IFeatureToggle } from 'interfaces/featureToggle'; | ||||
| import { getTogglePath } from 'utils/routePathHelpers'; | ||||
| import { FeatureSchema } from 'openapi'; | ||||
| 
 | ||||
| interface IRedirectParams { | ||||
|     name: string; | ||||
| @ -10,12 +10,12 @@ interface IRedirectParams { | ||||
| 
 | ||||
| const RedirectFeatureView = () => { | ||||
|     const { name } = useParams<IRedirectParams>(); | ||||
|     const { features } = useFeatures(); | ||||
|     const [featureToggle, setFeatureToggle] = useState<IFeatureToggle>(); | ||||
|     const { features = [] } = useFeatures(); | ||||
|     const [featureToggle, setFeatureToggle] = useState<FeatureSchema>(); | ||||
| 
 | ||||
|     useEffect(() => { | ||||
|         const toggle = features.find( | ||||
|             (toggle: IFeatureToggle) => toggle.name === name | ||||
|             (toggle: FeatureSchema) => toggle.name === name | ||||
|         ); | ||||
| 
 | ||||
|         setFeatureToggle(toggle); | ||||
|  | ||||
| @ -4,11 +4,11 @@ import ConditionallyRender from 'component/common/ConditionallyRender'; | ||||
| import ReportToggleList from 'component/Reporting/ReportToggleList/ReportToggleList'; | ||||
| import { ReportCard } from 'component/Reporting/ReportCard/ReportCard'; | ||||
| 
 | ||||
| interface ProjectHealthProps { | ||||
| interface IProjectHealthProps { | ||||
|     projectId: string; | ||||
| } | ||||
| 
 | ||||
| const ProjectHealth = ({ projectId }: ProjectHealthProps) => { | ||||
| const ProjectHealth = ({ projectId }: IProjectHealthProps) => { | ||||
|     const { healthReport, refetchHealthReport, error } = | ||||
|         useHealthReport(projectId); | ||||
| 
 | ||||
|  | ||||
| @ -3,11 +3,11 @@ import { ProjectFeatureToggles } from './ProjectFeatureToggles/ProjectFeatureTog | ||||
| import ProjectInfo from './ProjectInfo/ProjectInfo'; | ||||
| import { useStyles } from './Project.styles'; | ||||
| 
 | ||||
| interface ProjectOverviewProps { | ||||
| interface IProjectOverviewProps { | ||||
|     projectId: string; | ||||
| } | ||||
| 
 | ||||
| const ProjectOverview = ({ projectId }: ProjectOverviewProps) => { | ||||
| const ProjectOverview = ({ projectId }: IProjectOverviewProps) => { | ||||
|     const { project, loading } = useProject(projectId, { | ||||
|         refreshInterval: 10000, | ||||
|     }); | ||||
|  | ||||
| @ -23,11 +23,13 @@ import { getEnabledEnvs } from './helpers'; | ||||
| import StringTruncator from 'component/common/StringTruncator/StringTruncator'; | ||||
| import { useCommonStyles } from 'themes/commonStyles'; | ||||
| 
 | ||||
| interface ProjectEnvironmentListProps { | ||||
| interface IProjectEnvironmentListProps { | ||||
|     projectId: string; | ||||
| } | ||||
| 
 | ||||
| const ProjectEnvironmentList = ({ projectId }: ProjectEnvironmentListProps) => { | ||||
| const ProjectEnvironmentList = ({ | ||||
|     projectId, | ||||
| }: IProjectEnvironmentListProps) => { | ||||
|     // api state
 | ||||
|     const [envs, setEnvs] = useState<IProjectEnvironment[]>([]); | ||||
|     const { setToastData, setToastApiError } = useToast(); | ||||
|  | ||||
| @ -13,12 +13,12 @@ import styles from '../../strategies.module.scss'; | ||||
| import { TogglesLinkList } from 'component/strategies/TogglesLinkList/TogglesLinkList'; | ||||
| import { IParameter, IStrategy } from 'interfaces/strategy'; | ||||
| import { IApplication } from 'interfaces/application'; | ||||
| import { IFeatureToggle } from 'interfaces/featureToggle'; | ||||
| import { FeatureSchema } from 'openapi'; | ||||
| 
 | ||||
| interface IStrategyDetailsProps { | ||||
|     strategy: IStrategy; | ||||
|     applications: IApplication[]; | ||||
|     toggles: IFeatureToggle[]; | ||||
|     toggles: FeatureSchema[]; | ||||
| } | ||||
| 
 | ||||
| export const StrategyDetails = ({ | ||||
|  | ||||
| @ -14,7 +14,7 @@ import ConditionallyRender from 'component/common/ConditionallyRender'; | ||||
| export const StrategyView = () => { | ||||
|     const { name } = useParams<{ name: string }>(); | ||||
|     const { strategies } = useStrategies(); | ||||
|     const { features } = useFeatures(); | ||||
|     const { features = [] } = useFeatures(); | ||||
|     const { applications } = useApplications(); | ||||
|     const history = useHistory(); | ||||
| 
 | ||||
|  | ||||
| @ -9,10 +9,10 @@ import { Pause, PlayArrow } from '@material-ui/icons'; | ||||
| import styles from 'component/common/common.module.scss'; | ||||
| import { Link } from 'react-router-dom'; | ||||
| import ConditionallyRender from 'component/common/ConditionallyRender'; | ||||
| import { IFeatureToggle } from 'interfaces/featureToggle'; | ||||
| import { FeatureSchema } from 'openapi'; | ||||
| 
 | ||||
| interface ITogglesLinkListProps { | ||||
|     toggles: IFeatureToggle[]; | ||||
|     toggles: FeatureSchema[]; | ||||
| } | ||||
| 
 | ||||
| export const TogglesLinkList = ({ toggles }: ITogglesLinkListProps) => ( | ||||
|  | ||||
| @ -8,13 +8,11 @@ Object { | ||||
|   }, | ||||
|   "filtered": Array [ | ||||
|     Object { | ||||
|       "archived": false, | ||||
|       "createdAt": "2006-01-02T15:04:05Z", | ||||
|       "createdAt": 2006-01-02T15:04:05.000Z, | ||||
|       "description": "1", | ||||
|       "enabled": false, | ||||
|       "environments": Array [], | ||||
|       "impressionData": false, | ||||
|       "lastSeenAt": "2006-01-02T15:04:05Z", | ||||
|       "lastSeenAt": 2006-01-02T15:04:05.000Z, | ||||
|       "name": "1", | ||||
|       "project": "a", | ||||
|       "stale": false, | ||||
| @ -80,13 +78,11 @@ Object { | ||||
|   }, | ||||
|   "filtered": Array [ | ||||
|     Object { | ||||
|       "archived": false, | ||||
|       "createdAt": "2006-01-02T15:04:05Z", | ||||
|       "createdAt": 2006-01-02T15:04:05.000Z, | ||||
|       "description": "1", | ||||
|       "enabled": false, | ||||
|       "environments": Array [], | ||||
|       "impressionData": false, | ||||
|       "lastSeenAt": "2006-01-02T15:04:05Z", | ||||
|       "lastSeenAt": 2006-01-02T15:04:05.000Z, | ||||
|       "name": "1", | ||||
|       "project": "1", | ||||
|       "stale": false, | ||||
| @ -95,13 +91,11 @@ Object { | ||||
|       "variants": Array [], | ||||
|     }, | ||||
|     Object { | ||||
|       "archived": false, | ||||
|       "createdAt": "2006-01-02T15:04:05Z", | ||||
|       "createdAt": 2006-01-02T15:04:05.000Z, | ||||
|       "description": "1", | ||||
|       "enabled": false, | ||||
|       "environments": Array [], | ||||
|       "impressionData": false, | ||||
|       "lastSeenAt": "2006-01-02T15:04:05Z", | ||||
|       "lastSeenAt": 2006-01-02T15:04:05.000Z, | ||||
|       "name": "1", | ||||
|       "project": "1", | ||||
|       "stale": false, | ||||
| @ -110,13 +104,11 @@ Object { | ||||
|       "variants": Array [], | ||||
|     }, | ||||
|     Object { | ||||
|       "archived": false, | ||||
|       "createdAt": "2006-01-02T15:04:05Z", | ||||
|       "createdAt": 2006-01-02T15:04:05.000Z, | ||||
|       "description": "1", | ||||
|       "enabled": false, | ||||
|       "environments": Array [], | ||||
|       "impressionData": false, | ||||
|       "lastSeenAt": "2006-01-02T15:04:05Z", | ||||
|       "lastSeenAt": 2006-01-02T15:04:05.000Z, | ||||
|       "name": "1", | ||||
|       "project": "1", | ||||
|       "stale": false, | ||||
| @ -136,13 +128,11 @@ Object { | ||||
|   }, | ||||
|   "filtered": Array [ | ||||
|     Object { | ||||
|       "archived": false, | ||||
|       "createdAt": "2006-01-02T15:04:05Z", | ||||
|       "createdAt": 2006-01-02T15:04:05.000Z, | ||||
|       "description": "1", | ||||
|       "enabled": false, | ||||
|       "environments": Array [], | ||||
|       "impressionData": false, | ||||
|       "lastSeenAt": "2006-01-02T15:04:05Z", | ||||
|       "lastSeenAt": 2006-01-02T15:04:05.000Z, | ||||
|       "name": "1", | ||||
|       "project": "2", | ||||
|       "stale": false, | ||||
| @ -151,13 +141,11 @@ Object { | ||||
|       "variants": Array [], | ||||
|     }, | ||||
|     Object { | ||||
|       "archived": false, | ||||
|       "createdAt": "2006-01-02T15:04:05Z", | ||||
|       "createdAt": 2006-01-02T15:04:05.000Z, | ||||
|       "description": "1", | ||||
|       "enabled": false, | ||||
|       "environments": Array [], | ||||
|       "impressionData": false, | ||||
|       "lastSeenAt": "2006-01-02T15:04:05Z", | ||||
|       "lastSeenAt": 2006-01-02T15:04:05.000Z, | ||||
|       "name": "1", | ||||
|       "project": "2", | ||||
|       "stale": false, | ||||
| @ -178,13 +166,11 @@ Object { | ||||
|   }, | ||||
|   "filtered": Array [ | ||||
|     Object { | ||||
|       "archived": false, | ||||
|       "createdAt": "2006-01-02T15:04:05Z", | ||||
|       "createdAt": 2006-01-02T15:04:05.000Z, | ||||
|       "description": "1", | ||||
|       "enabled": false, | ||||
|       "environments": Array [], | ||||
|       "impressionData": false, | ||||
|       "lastSeenAt": "2006-01-02T15:04:05Z", | ||||
|       "lastSeenAt": 2006-01-02T15:04:05.000Z, | ||||
|       "name": "1", | ||||
|       "project": "abc", | ||||
|       "stale": false, | ||||
| @ -193,13 +179,11 @@ Object { | ||||
|       "variants": Array [], | ||||
|     }, | ||||
|     Object { | ||||
|       "archived": false, | ||||
|       "createdAt": "2006-01-02T15:04:05Z", | ||||
|       "createdAt": 2006-01-02T15:04:05.000Z, | ||||
|       "description": "1", | ||||
|       "enabled": false, | ||||
|       "environments": Array [], | ||||
|       "impressionData": false, | ||||
|       "lastSeenAt": "2006-01-02T15:04:05Z", | ||||
|       "lastSeenAt": 2006-01-02T15:04:05.000Z, | ||||
|       "name": "1", | ||||
|       "project": "abcd", | ||||
|       "stale": false, | ||||
|  | ||||
| @ -1,8 +1,9 @@ | ||||
| import { IFeatureTogglePayload } from 'interfaces/featureToggle'; | ||||
| import { ITag } from 'interfaces/tags'; | ||||
| import useAPI from '../useApi/useApi'; | ||||
| import { Operation } from 'fast-json-patch'; | ||||
| import { IConstraint } from 'interfaces/strategy'; | ||||
| import { CreateFeatureSchema } from 'openapi'; | ||||
| import { openApiAdmin } from 'utils/openapiClient'; | ||||
| 
 | ||||
| const useFeatureApi = () => { | ||||
|     const { makeRequest, createRequest, errors, loading } = useAPI({ | ||||
| @ -38,21 +39,12 @@ const useFeatureApi = () => { | ||||
| 
 | ||||
|     const createFeatureToggle = async ( | ||||
|         projectId: string, | ||||
|         featureToggle: IFeatureTogglePayload | ||||
|         createFeatureSchema: CreateFeatureSchema | ||||
|     ) => { | ||||
|         const path = `api/admin/projects/${projectId}/features`; | ||||
|         const req = createRequest(path, { | ||||
|             method: 'POST', | ||||
|             body: JSON.stringify(featureToggle), | ||||
|         return openApiAdmin.apiAdminProjectsProjectIdFeaturesPost({ | ||||
|             projectId, | ||||
|             createFeatureSchema, | ||||
|         }); | ||||
| 
 | ||||
|         try { | ||||
|             const res = await makeRequest(req.caller, req.id); | ||||
| 
 | ||||
|             return res; | ||||
|         } catch (e) { | ||||
|             throw e; | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     const toggleFeatureEnvironmentOn = async ( | ||||
|  | ||||
							
								
								
									
										30
									
								
								frontend/src/hooks/api/getters/useApiGetter/useApiGetter.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								frontend/src/hooks/api/getters/useApiGetter/useApiGetter.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| import useSWR, { SWRConfiguration, mutate } from 'swr'; | ||||
| import { useCallback } from 'react'; | ||||
| 
 | ||||
| type CacheKey = 'apiAdminFeaturesGet' | 'apiAdminArchiveFeaturesGet'; | ||||
| 
 | ||||
| interface IUseApiGetterOutput<T> { | ||||
|     data?: T; | ||||
|     refetch: () => void; | ||||
|     error?: Error | undefined; | ||||
|     loading: boolean; | ||||
| } | ||||
| 
 | ||||
| export const useApiGetter = <T>( | ||||
|     cacheKey: CacheKey, | ||||
|     fetcher: () => Promise<T>, | ||||
|     options?: SWRConfiguration | ||||
| ): IUseApiGetterOutput<T> => { | ||||
|     const { data, error } = useSWR<T>(cacheKey, fetcher, options); | ||||
| 
 | ||||
|     const refetch = useCallback(() => { | ||||
|         mutate(cacheKey).catch(console.warn); | ||||
|     }, [cacheKey]); | ||||
| 
 | ||||
|     return { | ||||
|         data, | ||||
|         error, | ||||
|         refetch, | ||||
|         loading: !error && !data, | ||||
|     }; | ||||
| }; | ||||
| @ -1,39 +1,24 @@ | ||||
| import useSWR, { mutate, SWRConfiguration } from 'swr'; | ||||
| import { useCallback } from 'react'; | ||||
| import { formatApiPath } from 'utils/formatPath'; | ||||
| import handleErrorResponses from '../httpErrorResponseHandler'; | ||||
| import { IFeatureToggle } from 'interfaces/featureToggle'; | ||||
| 
 | ||||
| const PATH = formatApiPath('api/admin/features'); | ||||
| import { FeatureSchema } from 'openapi'; | ||||
| import { openApiAdmin } from 'utils/openapiClient'; | ||||
| import { useApiGetter } from 'hooks/api/getters/useApiGetter/useApiGetter'; | ||||
| 
 | ||||
| export interface IUseFeaturesOutput { | ||||
|     features: IFeatureToggle[]; | ||||
|     features?: FeatureSchema[]; | ||||
|     refetchFeatures: () => void; | ||||
|     loading: boolean; | ||||
|     error?: Error; | ||||
| } | ||||
| 
 | ||||
| export const useFeatures = (options?: SWRConfiguration): IUseFeaturesOutput => { | ||||
|     const { data, error } = useSWR<{ features: IFeatureToggle[] }>( | ||||
|         PATH, | ||||
|         fetchFeatures, | ||||
|         options | ||||
| export const useFeatures = (): IUseFeaturesOutput => { | ||||
|     const { data, refetch, loading, error } = useApiGetter( | ||||
|         'apiAdminFeaturesGet', | ||||
|         () => openApiAdmin.apiAdminFeaturesGet() | ||||
|     ); | ||||
| 
 | ||||
|     const refetchFeatures = useCallback(() => { | ||||
|         mutate(PATH).catch(console.warn); | ||||
|     }, []); | ||||
| 
 | ||||
|     return { | ||||
|         features: data?.features || [], | ||||
|         loading: !error && !data, | ||||
|         refetchFeatures, | ||||
|         features: data?.features, | ||||
|         refetchFeatures: refetch, | ||||
|         loading, | ||||
|         error, | ||||
|     }; | ||||
| }; | ||||
| 
 | ||||
| const fetchFeatures = () => { | ||||
|     return fetch(PATH, { method: 'GET' }) | ||||
|         .then(handleErrorResponses('Features')) | ||||
|         .then(res => res.json()); | ||||
| }; | ||||
|  | ||||
| @ -1,41 +1,24 @@ | ||||
| import useSWR, { mutate, SWRConfiguration } from 'swr'; | ||||
| import { useCallback } from 'react'; | ||||
| import { formatApiPath } from 'utils/formatPath'; | ||||
| import handleErrorResponses from '../httpErrorResponseHandler'; | ||||
| import { IFeatureToggle } from 'interfaces/featureToggle'; | ||||
| import { openApiAdmin } from 'utils/openapiClient'; | ||||
| import { FeatureSchema } from 'openapi'; | ||||
| import { useApiGetter } from 'hooks/api/getters/useApiGetter/useApiGetter'; | ||||
| 
 | ||||
| const PATH = formatApiPath('api/admin/archive/features'); | ||||
| 
 | ||||
| export interface UseFeaturesArchiveOutput { | ||||
|     archivedFeatures: IFeatureToggle[]; | ||||
| export interface IUseFeaturesArchiveOutput { | ||||
|     archivedFeatures?: FeatureSchema[]; | ||||
|     refetchArchived: () => void; | ||||
|     loading: boolean; | ||||
|     error?: Error; | ||||
| } | ||||
| 
 | ||||
| export const useFeaturesArchive = ( | ||||
|     options?: SWRConfiguration | ||||
| ): UseFeaturesArchiveOutput => { | ||||
|     const { data, error } = useSWR<{ features: IFeatureToggle[] }>( | ||||
|         PATH, | ||||
|         fetchArchivedFeatures, | ||||
|         options | ||||
| export const useFeaturesArchive = (): IUseFeaturesArchiveOutput => { | ||||
|     const { data, refetch, loading, error } = useApiGetter( | ||||
|         'apiAdminArchiveFeaturesGet', | ||||
|         () => openApiAdmin.apiAdminArchiveFeaturesGet() | ||||
|     ); | ||||
| 
 | ||||
|     const refetchArchived = useCallback(() => { | ||||
|         mutate(PATH).catch(console.warn); | ||||
|     }, []); | ||||
| 
 | ||||
|     return { | ||||
|         archivedFeatures: data?.features || [], | ||||
|         refetchArchived, | ||||
|         loading: !error && !data, | ||||
|         archivedFeatures: data?.features, | ||||
|         refetchArchived: refetch, | ||||
|         loading, | ||||
|         error, | ||||
|     }; | ||||
| }; | ||||
| 
 | ||||
| const fetchArchivedFeatures = () => { | ||||
|     return fetch(PATH, { method: 'GET' }) | ||||
|         .then(handleErrorResponses('Archive')) | ||||
|         .then(res => res.json()); | ||||
| }; | ||||
|  | ||||
| @ -4,14 +4,14 @@ import { formatApiPath } from 'utils/formatPath'; | ||||
| import handleErrorResponses from '../httpErrorResponseHandler'; | ||||
| import { ISegment } from 'interfaces/segment'; | ||||
| 
 | ||||
| export interface UseSegmentOutput { | ||||
| export interface IUseSegmentOutput { | ||||
|     segment?: ISegment; | ||||
|     refetchSegment: () => void; | ||||
|     loading: boolean; | ||||
|     error?: Error; | ||||
| } | ||||
| 
 | ||||
| export const useSegment = (id: number): UseSegmentOutput => { | ||||
| export const useSegment = (id: number): IUseSegmentOutput => { | ||||
|     const path = formatApiPath(`api/admin/segments/${id}`); | ||||
|     const { data, error } = useSWR<ISegment>(path, () => fetchSegment(path)); | ||||
| 
 | ||||
|  | ||||
| @ -6,14 +6,14 @@ import { ISegment } from 'interfaces/segment'; | ||||
| import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; | ||||
| import { IFlags } from 'interfaces/uiConfig'; | ||||
| 
 | ||||
| export interface UseSegmentsOutput { | ||||
| export interface IUseSegmentsOutput { | ||||
|     segments?: ISegment[]; | ||||
|     refetchSegments: () => void; | ||||
|     loading: boolean; | ||||
|     error?: Error; | ||||
| } | ||||
| 
 | ||||
| export const useSegments = (strategyId?: string): UseSegmentsOutput => { | ||||
| export const useSegments = (strategyId?: string): IUseSegmentsOutput => { | ||||
|     const { uiConfig } = useUiConfig(); | ||||
| 
 | ||||
|     const { data, error, mutate } = useSWR( | ||||
|  | ||||
| @ -4,7 +4,7 @@ import { formatApiPath } from 'utils/formatPath'; | ||||
| import handleErrorResponses from '../httpErrorResponseHandler'; | ||||
| import { IFeatureStrategy } from 'interfaces/strategy'; | ||||
| 
 | ||||
| export interface useStrategiesBySegmentOutput { | ||||
| export interface IUseStrategiesBySegmentOutput { | ||||
|     strategies?: IFeatureStrategy[]; | ||||
|     refetchUsedSegments: () => void; | ||||
|     loading: boolean; | ||||
| @ -13,7 +13,7 @@ export interface useStrategiesBySegmentOutput { | ||||
| 
 | ||||
| export const useStrategiesBySegment = ( | ||||
|     id: number | ||||
| ): useStrategiesBySegmentOutput => { | ||||
| ): IUseStrategiesBySegmentOutput => { | ||||
|     const path = formatApiPath(`api/admin/segments/${id}/strategies`); | ||||
|     const { data, error } = useSWR(path, () => fetchUsedSegment(path)); | ||||
| 
 | ||||
|  | ||||
| @ -1,7 +1,8 @@ | ||||
| import { renderHook, act } from '@testing-library/react-hooks'; | ||||
| import { useFeaturesFilter } from 'hooks/useFeaturesFilter'; | ||||
| import { IFeatureToggle } from 'interfaces/featureToggle'; | ||||
| import { IConstraint, IFeatureStrategy } from 'interfaces/strategy'; | ||||
| import { FeatureSchema } from 'openapi'; | ||||
| import parseISO from 'date-fns/parseISO'; | ||||
| 
 | ||||
| test('useFeaturesFilter empty', () => { | ||||
|     const { result } = renderHook(() => useFeaturesFilter([])); | ||||
| @ -88,22 +89,20 @@ test('useFeaturesFilter constraints', () => { | ||||
| }); | ||||
| 
 | ||||
| const mockFeatureToggle = ( | ||||
|     overrides?: Partial<IFeatureToggle> | ||||
| ): IFeatureToggle => { | ||||
|     overrides?: Partial<FeatureSchema> | ||||
| ): FeatureSchema => { | ||||
|     return { | ||||
|         name: '1', | ||||
|         description: '1', | ||||
|         type: '1', | ||||
|         project: '1', | ||||
|         archived: false, | ||||
|         enabled: false, | ||||
|         stale: false, | ||||
|         impressionData: false, | ||||
|         strategies: [], | ||||
|         variants: [], | ||||
|         environments: [], | ||||
|         createdAt: '2006-01-02T15:04:05Z', | ||||
|         lastSeenAt: '2006-01-02T15:04:05Z', | ||||
|         createdAt: parseISO('2006-01-02T15:04:05Z'), | ||||
|         lastSeenAt: parseISO('2006-01-02T15:04:05Z'), | ||||
|         ...overrides, | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| import { IFeatureToggle } from 'interfaces/featureToggle'; | ||||
| import React, { useMemo } from 'react'; | ||||
| import { createGlobalStateHook } from 'hooks/useGlobalState'; | ||||
| import { FeatureSchema } from 'openapi'; | ||||
| 
 | ||||
| export interface IFeaturesFilter { | ||||
|     query?: string; | ||||
| @ -8,7 +8,7 @@ export interface IFeaturesFilter { | ||||
| } | ||||
| 
 | ||||
| export interface IFeaturesSortOutput { | ||||
|     filtered: IFeatureToggle[]; | ||||
|     filtered: FeatureSchema[]; | ||||
|     filter: IFeaturesFilter; | ||||
|     setFilter: React.Dispatch<React.SetStateAction<IFeaturesFilter>>; | ||||
| } | ||||
| @ -21,7 +21,7 @@ const useFeaturesFilterState = createGlobalStateHook<IFeaturesFilter>( | ||||
| ); | ||||
| 
 | ||||
| export const useFeaturesFilter = ( | ||||
|     features: IFeatureToggle[] | ||||
|     features: FeatureSchema[] | ||||
| ): IFeaturesSortOutput => { | ||||
|     const [filter, setFilter] = useFeaturesFilterState(); | ||||
| 
 | ||||
| @ -37,9 +37,9 @@ export const useFeaturesFilter = ( | ||||
| }; | ||||
| 
 | ||||
| const filterFeatures = ( | ||||
|     features: IFeatureToggle[], | ||||
|     features: FeatureSchema[], | ||||
|     filter: IFeaturesFilter | ||||
| ): IFeatureToggle[] => { | ||||
| ): FeatureSchema[] => { | ||||
|     return filterFeaturesByQuery( | ||||
|         filterFeaturesByProject(features, filter), | ||||
|         filter | ||||
| @ -47,18 +47,18 @@ const filterFeatures = ( | ||||
| }; | ||||
| 
 | ||||
| const filterFeaturesByProject = ( | ||||
|     features: IFeatureToggle[], | ||||
|     features: FeatureSchema[], | ||||
|     filter: IFeaturesFilter | ||||
| ): IFeatureToggle[] => { | ||||
| ): FeatureSchema[] => { | ||||
|     return filter.project === '*' | ||||
|         ? features | ||||
|         : features.filter(f => f.project === filter.project); | ||||
| }; | ||||
| 
 | ||||
| const filterFeaturesByQuery = ( | ||||
|     features: IFeatureToggle[], | ||||
|     features: FeatureSchema[], | ||||
|     filter: IFeaturesFilter | ||||
| ): IFeatureToggle[] => { | ||||
| ): FeatureSchema[] => { | ||||
|     if (!filter.query) { | ||||
|         return features; | ||||
|     } | ||||
| @ -78,11 +78,14 @@ const filterFeaturesByQuery = ( | ||||
| }; | ||||
| 
 | ||||
| const filterFeatureByRegExp = ( | ||||
|     feature: IFeatureToggle, | ||||
|     feature: FeatureSchema, | ||||
|     filter: IFeaturesFilter, | ||||
|     regExp: RegExp | ||||
| ): boolean => { | ||||
|     if (regExp.test(feature.name) || regExp.test(feature.description)) { | ||||
|     if ( | ||||
|         regExp.test(feature.name) || | ||||
|         (feature.description && regExp.test(feature.description)) | ||||
|     ) { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -1,13 +1,12 @@ | ||||
| import { IFeatureToggle } from '../interfaces/featureToggle'; | ||||
| import React, { useMemo } from 'react'; | ||||
| import { getBasePath } from 'utils/formatPath'; | ||||
| import { createPersistentGlobalStateHook } from './usePersistentGlobalState'; | ||||
| import { parseISO } from 'date-fns'; | ||||
| import { | ||||
|     expired, | ||||
|     getDiffInDays, | ||||
|     toggleExpiryByTypeMap, | ||||
| } from 'component/Reporting/utils'; | ||||
| import { FeatureSchema } from 'openapi'; | ||||
| 
 | ||||
| type FeaturesSortType = | ||||
|     | 'name' | ||||
| @ -27,7 +26,7 @@ interface IFeaturesSort { | ||||
| 
 | ||||
| export interface IFeaturesSortOutput { | ||||
|     sort: IFeaturesSort; | ||||
|     sorted: IFeatureToggle[]; | ||||
|     sorted: FeatureSchema[]; | ||||
|     setSort: React.Dispatch<React.SetStateAction<IFeaturesSort>>; | ||||
| } | ||||
| 
 | ||||
| @ -44,7 +43,7 @@ const useFeaturesSortState = createPersistentGlobalStateHook<IFeaturesSort>( | ||||
| ); | ||||
| 
 | ||||
| export const useFeaturesSort = ( | ||||
|     features: IFeatureToggle[] | ||||
|     features: FeatureSchema[] | ||||
| ): IFeaturesSortOutput => { | ||||
|     const [sort, setSort] = useFeaturesSortState(); | ||||
| 
 | ||||
| @ -73,9 +72,9 @@ export const createFeaturesFilterSortOptions = | ||||
|     }; | ||||
| 
 | ||||
| const sortAscendingFeatures = ( | ||||
|     features: IFeatureToggle[], | ||||
|     features: FeatureSchema[], | ||||
|     sort: IFeaturesSort | ||||
| ): IFeatureToggle[] => { | ||||
| ): FeatureSchema[] => { | ||||
|     switch (sort.type) { | ||||
|         case 'enabled': | ||||
|             return sortByEnabled(features); | ||||
| @ -102,9 +101,9 @@ const sortAscendingFeatures = ( | ||||
| }; | ||||
| 
 | ||||
| const sortFeatures = ( | ||||
|     features: IFeatureToggle[], | ||||
|     features: FeatureSchema[], | ||||
|     sort: IFeaturesSort | ||||
| ): IFeatureToggle[] => { | ||||
| ): FeatureSchema[] => { | ||||
|     const sorted = sortAscendingFeatures(features, sort); | ||||
| 
 | ||||
|     if (sort.desc) { | ||||
| @ -115,84 +114,97 @@ const sortFeatures = ( | ||||
| }; | ||||
| 
 | ||||
| const sortByEnabled = ( | ||||
|     features: Readonly<IFeatureToggle[]> | ||||
| ): IFeatureToggle[] => { | ||||
|     features: Readonly<FeatureSchema[]> | ||||
| ): FeatureSchema[] => { | ||||
|     return [...features].sort((a, b) => | ||||
|         a.enabled === b.enabled ? 0 : a.enabled ? -1 : 1 | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| const sortByStale = ( | ||||
|     features: Readonly<IFeatureToggle[]> | ||||
| ): IFeatureToggle[] => { | ||||
| const sortByStale = (features: Readonly<FeatureSchema[]>): FeatureSchema[] => { | ||||
|     return [...features].sort((a, b) => | ||||
|         a.stale === b.stale ? 0 : a.stale ? -1 : 1 | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| const sortByLastSeen = ( | ||||
|     features: Readonly<IFeatureToggle[]> | ||||
| ): IFeatureToggle[] => { | ||||
|     features: Readonly<FeatureSchema[]> | ||||
| ): FeatureSchema[] => { | ||||
|     return [...features].sort((a, b) => | ||||
|         a.lastSeenAt && b.lastSeenAt | ||||
|             ? b.lastSeenAt.localeCompare(a.lastSeenAt) | ||||
|             ? compareNullableDates(b.lastSeenAt, a.lastSeenAt) | ||||
|             : a.lastSeenAt | ||||
|             ? -1 | ||||
|             : b.lastSeenAt | ||||
|             ? 1 | ||||
|             : b.createdAt.localeCompare(a.createdAt) | ||||
|             : compareNullableDates(b.createdAt, a.createdAt) | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| const sortByCreated = ( | ||||
|     features: Readonly<IFeatureToggle[]> | ||||
| ): IFeatureToggle[] => { | ||||
|     return [...features].sort((a, b) => b.createdAt.localeCompare(a.createdAt)); | ||||
|     features: Readonly<FeatureSchema[]> | ||||
| ): FeatureSchema[] => { | ||||
|     return [...features].sort((a, b) => | ||||
|         compareNullableDates(b.createdAt, a.createdAt) | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| const sortByName = (features: Readonly<IFeatureToggle[]>): IFeatureToggle[] => { | ||||
| const sortByName = (features: Readonly<FeatureSchema[]>): FeatureSchema[] => { | ||||
|     return [...features].sort((a, b) => a.name.localeCompare(b.name)); | ||||
| }; | ||||
| 
 | ||||
| const sortByProject = ( | ||||
|     features: Readonly<IFeatureToggle[]> | ||||
| ): IFeatureToggle[] => { | ||||
|     features: Readonly<FeatureSchema[]> | ||||
| ): FeatureSchema[] => { | ||||
|     return [...features].sort((a, b) => a.project.localeCompare(b.project)); | ||||
| }; | ||||
| 
 | ||||
| const sortByType = (features: Readonly<IFeatureToggle[]>): IFeatureToggle[] => { | ||||
|     return [...features].sort((a, b) => a.type.localeCompare(b.type)); | ||||
| const sortByType = (features: Readonly<FeatureSchema[]>): FeatureSchema[] => { | ||||
|     return [...features].sort((a, b) => | ||||
|         a.type && b.type | ||||
|             ? a.type.localeCompare(b.type) | ||||
|             : a.type | ||||
|             ? 1 | ||||
|             : b.type | ||||
|             ? -1 | ||||
|             : 0 | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| const compareNullableDates = ( | ||||
|     a: Date | null | undefined, | ||||
|     b: Date | null | undefined | ||||
| ): number => { | ||||
|     return a && b ? a.getTime() - b.getTime() : a ? 1 : b ? -1 : 0; | ||||
| }; | ||||
| const sortByExpired = ( | ||||
|     features: Readonly<IFeatureToggle[]> | ||||
| ): IFeatureToggle[] => { | ||||
|     features: Readonly<FeatureSchema[]> | ||||
| ): FeatureSchema[] => { | ||||
|     return [...features].sort((a, b) => { | ||||
|         const now = new Date(); | ||||
|         const dateA = parseISO(a.createdAt); | ||||
|         const dateB = parseISO(b.createdAt); | ||||
|         const dateA = a.createdAt!; | ||||
|         const dateB = b.createdAt!; | ||||
| 
 | ||||
|         const diffA = getDiffInDays(dateA, now); | ||||
|         const diffB = getDiffInDays(dateB, now); | ||||
| 
 | ||||
|         if (!expired(diffA, a.type) && expired(diffB, b.type)) { | ||||
|         if (!expired(diffA, a.type!) && expired(diffB, b.type!)) { | ||||
|             return 1; | ||||
|         } | ||||
| 
 | ||||
|         if (expired(diffA, a.type) && !expired(diffB, b.type)) { | ||||
|         if (expired(diffA, a.type!) && !expired(diffB, b.type!)) { | ||||
|             return -1; | ||||
|         } | ||||
| 
 | ||||
|         const expiration = toggleExpiryByTypeMap as Record<string, number>; | ||||
|         const expiredByA = diffA - expiration[a.type]; | ||||
|         const expiredByB = diffB - expiration[b.type]; | ||||
|         const expiredByA = a.type ? diffA - expiration[a.type] : 0; | ||||
|         const expiredByB = b.type ? diffB - expiration[b.type] : 0; | ||||
| 
 | ||||
|         return expiredByB - expiredByA; | ||||
|     }); | ||||
| }; | ||||
| 
 | ||||
| const sortByStatus = ( | ||||
|     features: Readonly<IFeatureToggle[]> | ||||
| ): IFeatureToggle[] => { | ||||
| const sortByStatus = (features: Readonly<FeatureSchema[]>): FeatureSchema[] => { | ||||
|     return [...features].sort((a, b) => { | ||||
|         if (a.stale) { | ||||
|             return 1; | ||||
|  | ||||
							
								
								
									
										262
									
								
								frontend/src/openapi/apis/AdminApi.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										262
									
								
								frontend/src/openapi/apis/AdminApi.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,262 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| /** | ||||
|  * Unleash API | ||||
|  * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 | ||||
|  * | ||||
|  * The version of the OpenAPI document: 4.10.0-beta.1 | ||||
|  *  | ||||
|  * | ||||
|  * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 | ||||
|  * https://openapi-generator.tech
 | ||||
|  * Do not edit the class manually. | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| import * as runtime from '../runtime'; | ||||
| import { | ||||
|     ChangeProjectSchema, | ||||
|     ChangeProjectSchemaFromJSON, | ||||
|     ChangeProjectSchemaToJSON, | ||||
|     CreateFeatureSchema, | ||||
|     CreateFeatureSchemaFromJSON, | ||||
|     CreateFeatureSchemaToJSON, | ||||
|     FeatureSchema, | ||||
|     FeatureSchemaFromJSON, | ||||
|     FeatureSchemaToJSON, | ||||
|     FeaturesSchema, | ||||
|     FeaturesSchemaFromJSON, | ||||
|     FeaturesSchemaToJSON, | ||||
| } from '../models'; | ||||
| 
 | ||||
| export interface ApiAdminProjectsProjectIdFeaturesFeatureNameChangeProjectPostRequest { | ||||
|     projectId: string; | ||||
|     featureName: string; | ||||
|     changeProjectSchema: ChangeProjectSchema; | ||||
| } | ||||
| 
 | ||||
| export interface ApiAdminProjectsProjectIdFeaturesFeatureNameGetRequest { | ||||
|     projectId: string; | ||||
|     featureName: string; | ||||
| } | ||||
| 
 | ||||
| export interface ApiAdminProjectsProjectIdFeaturesGetRequest { | ||||
|     projectId: string; | ||||
| } | ||||
| 
 | ||||
| export interface ApiAdminProjectsProjectIdFeaturesPostRequest { | ||||
|     projectId: string; | ||||
|     createFeatureSchema: CreateFeatureSchema; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  *  | ||||
|  */ | ||||
| export class AdminApi extends runtime.BaseAPI { | ||||
| 
 | ||||
|     /** | ||||
|      */ | ||||
|     async apiAdminArchiveFeaturesGetRaw(initOverrides?: RequestInit): Promise<runtime.ApiResponse<FeaturesSchema>> { | ||||
|         const queryParameters: any = {}; | ||||
| 
 | ||||
|         const headerParameters: runtime.HTTPHeaders = {}; | ||||
| 
 | ||||
|         if (this.configuration && this.configuration.apiKey) { | ||||
|             headerParameters["Authorization"] = this.configuration.apiKey("Authorization"); // apiKey authentication
 | ||||
|         } | ||||
| 
 | ||||
|         const response = await this.request({ | ||||
|             path: `/api/admin/archive/features`, | ||||
|             method: 'GET', | ||||
|             headers: headerParameters, | ||||
|             query: queryParameters, | ||||
|         }, initOverrides); | ||||
| 
 | ||||
|         return new runtime.JSONApiResponse(response, (jsonValue) => FeaturesSchemaFromJSON(jsonValue)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      */ | ||||
|     async apiAdminArchiveFeaturesGet(initOverrides?: RequestInit): Promise<FeaturesSchema> { | ||||
|         const response = await this.apiAdminArchiveFeaturesGetRaw(initOverrides); | ||||
|         return await response.value(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      */ | ||||
|     async apiAdminFeaturesGetRaw(initOverrides?: RequestInit): Promise<runtime.ApiResponse<FeaturesSchema>> { | ||||
|         const queryParameters: any = {}; | ||||
| 
 | ||||
|         const headerParameters: runtime.HTTPHeaders = {}; | ||||
| 
 | ||||
|         if (this.configuration && this.configuration.apiKey) { | ||||
|             headerParameters["Authorization"] = this.configuration.apiKey("Authorization"); // apiKey authentication
 | ||||
|         } | ||||
| 
 | ||||
|         const response = await this.request({ | ||||
|             path: `/api/admin/features/`, | ||||
|             method: 'GET', | ||||
|             headers: headerParameters, | ||||
|             query: queryParameters, | ||||
|         }, initOverrides); | ||||
| 
 | ||||
|         return new runtime.JSONApiResponse(response, (jsonValue) => FeaturesSchemaFromJSON(jsonValue)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      */ | ||||
|     async apiAdminFeaturesGet(initOverrides?: RequestInit): Promise<FeaturesSchema> { | ||||
|         const response = await this.apiAdminFeaturesGetRaw(initOverrides); | ||||
|         return await response.value(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      */ | ||||
|     async apiAdminProjectsProjectIdFeaturesFeatureNameChangeProjectPostRaw(requestParameters: ApiAdminProjectsProjectIdFeaturesFeatureNameChangeProjectPostRequest, initOverrides?: RequestInit): Promise<runtime.ApiResponse<void>> { | ||||
|         if (requestParameters.projectId === null || requestParameters.projectId === undefined) { | ||||
|             throw new runtime.RequiredError('projectId','Required parameter requestParameters.projectId was null or undefined when calling apiAdminProjectsProjectIdFeaturesFeatureNameChangeProjectPost.'); | ||||
|         } | ||||
| 
 | ||||
|         if (requestParameters.featureName === null || requestParameters.featureName === undefined) { | ||||
|             throw new runtime.RequiredError('featureName','Required parameter requestParameters.featureName was null or undefined when calling apiAdminProjectsProjectIdFeaturesFeatureNameChangeProjectPost.'); | ||||
|         } | ||||
| 
 | ||||
|         if (requestParameters.changeProjectSchema === null || requestParameters.changeProjectSchema === undefined) { | ||||
|             throw new runtime.RequiredError('changeProjectSchema','Required parameter requestParameters.changeProjectSchema was null or undefined when calling apiAdminProjectsProjectIdFeaturesFeatureNameChangeProjectPost.'); | ||||
|         } | ||||
| 
 | ||||
|         const queryParameters: any = {}; | ||||
| 
 | ||||
|         const headerParameters: runtime.HTTPHeaders = {}; | ||||
| 
 | ||||
|         headerParameters['Content-Type'] = 'application/json'; | ||||
| 
 | ||||
|         if (this.configuration && this.configuration.apiKey) { | ||||
|             headerParameters["Authorization"] = this.configuration.apiKey("Authorization"); // apiKey authentication
 | ||||
|         } | ||||
| 
 | ||||
|         const response = await this.request({ | ||||
|             path: `/api/admin/projects/{projectId}/features/{featureName}/changeProject`.replace(`{${"projectId"}}`, encodeURIComponent(String(requestParameters.projectId))).replace(`{${"featureName"}}`, encodeURIComponent(String(requestParameters.featureName))), | ||||
|             method: 'POST', | ||||
|             headers: headerParameters, | ||||
|             query: queryParameters, | ||||
|             body: ChangeProjectSchemaToJSON(requestParameters.changeProjectSchema), | ||||
|         }, initOverrides); | ||||
| 
 | ||||
|         return new runtime.VoidApiResponse(response); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      */ | ||||
|     async apiAdminProjectsProjectIdFeaturesFeatureNameChangeProjectPost(requestParameters: ApiAdminProjectsProjectIdFeaturesFeatureNameChangeProjectPostRequest, initOverrides?: RequestInit): Promise<void> { | ||||
|         await this.apiAdminProjectsProjectIdFeaturesFeatureNameChangeProjectPostRaw(requestParameters, initOverrides); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      */ | ||||
|     async apiAdminProjectsProjectIdFeaturesFeatureNameGetRaw(requestParameters: ApiAdminProjectsProjectIdFeaturesFeatureNameGetRequest, initOverrides?: RequestInit): Promise<runtime.ApiResponse<FeatureSchema>> { | ||||
|         if (requestParameters.projectId === null || requestParameters.projectId === undefined) { | ||||
|             throw new runtime.RequiredError('projectId','Required parameter requestParameters.projectId was null or undefined when calling apiAdminProjectsProjectIdFeaturesFeatureNameGet.'); | ||||
|         } | ||||
| 
 | ||||
|         if (requestParameters.featureName === null || requestParameters.featureName === undefined) { | ||||
|             throw new runtime.RequiredError('featureName','Required parameter requestParameters.featureName was null or undefined when calling apiAdminProjectsProjectIdFeaturesFeatureNameGet.'); | ||||
|         } | ||||
| 
 | ||||
|         const queryParameters: any = {}; | ||||
| 
 | ||||
|         const headerParameters: runtime.HTTPHeaders = {}; | ||||
| 
 | ||||
|         if (this.configuration && this.configuration.apiKey) { | ||||
|             headerParameters["Authorization"] = this.configuration.apiKey("Authorization"); // apiKey authentication
 | ||||
|         } | ||||
| 
 | ||||
|         const response = await this.request({ | ||||
|             path: `/api/admin/projects/{projectId}/features/{featureName}`.replace(`{${"projectId"}}`, encodeURIComponent(String(requestParameters.projectId))).replace(`{${"featureName"}}`, encodeURIComponent(String(requestParameters.featureName))), | ||||
|             method: 'GET', | ||||
|             headers: headerParameters, | ||||
|             query: queryParameters, | ||||
|         }, initOverrides); | ||||
| 
 | ||||
|         return new runtime.JSONApiResponse(response, (jsonValue) => FeatureSchemaFromJSON(jsonValue)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      */ | ||||
|     async apiAdminProjectsProjectIdFeaturesFeatureNameGet(requestParameters: ApiAdminProjectsProjectIdFeaturesFeatureNameGetRequest, initOverrides?: RequestInit): Promise<FeatureSchema> { | ||||
|         const response = await this.apiAdminProjectsProjectIdFeaturesFeatureNameGetRaw(requestParameters, initOverrides); | ||||
|         return await response.value(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      */ | ||||
|     async apiAdminProjectsProjectIdFeaturesGetRaw(requestParameters: ApiAdminProjectsProjectIdFeaturesGetRequest, initOverrides?: RequestInit): Promise<runtime.ApiResponse<FeaturesSchema>> { | ||||
|         if (requestParameters.projectId === null || requestParameters.projectId === undefined) { | ||||
|             throw new runtime.RequiredError('projectId','Required parameter requestParameters.projectId was null or undefined when calling apiAdminProjectsProjectIdFeaturesGet.'); | ||||
|         } | ||||
| 
 | ||||
|         const queryParameters: any = {}; | ||||
| 
 | ||||
|         const headerParameters: runtime.HTTPHeaders = {}; | ||||
| 
 | ||||
|         if (this.configuration && this.configuration.apiKey) { | ||||
|             headerParameters["Authorization"] = this.configuration.apiKey("Authorization"); // apiKey authentication
 | ||||
|         } | ||||
| 
 | ||||
|         const response = await this.request({ | ||||
|             path: `/api/admin/projects/{projectId}/features`.replace(`{${"projectId"}}`, encodeURIComponent(String(requestParameters.projectId))), | ||||
|             method: 'GET', | ||||
|             headers: headerParameters, | ||||
|             query: queryParameters, | ||||
|         }, initOverrides); | ||||
| 
 | ||||
|         return new runtime.JSONApiResponse(response, (jsonValue) => FeaturesSchemaFromJSON(jsonValue)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      */ | ||||
|     async apiAdminProjectsProjectIdFeaturesGet(requestParameters: ApiAdminProjectsProjectIdFeaturesGetRequest, initOverrides?: RequestInit): Promise<FeaturesSchema> { | ||||
|         const response = await this.apiAdminProjectsProjectIdFeaturesGetRaw(requestParameters, initOverrides); | ||||
|         return await response.value(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      */ | ||||
|     async apiAdminProjectsProjectIdFeaturesPostRaw(requestParameters: ApiAdminProjectsProjectIdFeaturesPostRequest, initOverrides?: RequestInit): Promise<runtime.ApiResponse<FeatureSchema>> { | ||||
|         if (requestParameters.projectId === null || requestParameters.projectId === undefined) { | ||||
|             throw new runtime.RequiredError('projectId','Required parameter requestParameters.projectId was null or undefined when calling apiAdminProjectsProjectIdFeaturesPost.'); | ||||
|         } | ||||
| 
 | ||||
|         if (requestParameters.createFeatureSchema === null || requestParameters.createFeatureSchema === undefined) { | ||||
|             throw new runtime.RequiredError('createFeatureSchema','Required parameter requestParameters.createFeatureSchema was null or undefined when calling apiAdminProjectsProjectIdFeaturesPost.'); | ||||
|         } | ||||
| 
 | ||||
|         const queryParameters: any = {}; | ||||
| 
 | ||||
|         const headerParameters: runtime.HTTPHeaders = {}; | ||||
| 
 | ||||
|         headerParameters['Content-Type'] = 'application/json'; | ||||
| 
 | ||||
|         if (this.configuration && this.configuration.apiKey) { | ||||
|             headerParameters["Authorization"] = this.configuration.apiKey("Authorization"); // apiKey authentication
 | ||||
|         } | ||||
| 
 | ||||
|         const response = await this.request({ | ||||
|             path: `/api/admin/projects/{projectId}/features`.replace(`{${"projectId"}}`, encodeURIComponent(String(requestParameters.projectId))), | ||||
|             method: 'POST', | ||||
|             headers: headerParameters, | ||||
|             query: queryParameters, | ||||
|             body: CreateFeatureSchemaToJSON(requestParameters.createFeatureSchema), | ||||
|         }, initOverrides); | ||||
| 
 | ||||
|         return new runtime.JSONApiResponse(response, (jsonValue) => FeatureSchemaFromJSON(jsonValue)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      */ | ||||
|     async apiAdminProjectsProjectIdFeaturesPost(requestParameters: ApiAdminProjectsProjectIdFeaturesPostRequest, initOverrides?: RequestInit): Promise<FeatureSchema> { | ||||
|         const response = await this.apiAdminProjectsProjectIdFeaturesPostRaw(requestParameters, initOverrides); | ||||
|         return await response.value(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										3
									
								
								frontend/src/openapi/apis/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								frontend/src/openapi/apis/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| export * from './AdminApi'; | ||||
							
								
								
									
										5
									
								
								frontend/src/openapi/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								frontend/src/openapi/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| export * from './runtime'; | ||||
| export * from './apis'; | ||||
| export * from './models'; | ||||
							
								
								
									
										56
									
								
								frontend/src/openapi/models/ChangeProjectSchema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								frontend/src/openapi/models/ChangeProjectSchema.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,56 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| /** | ||||
|  * Unleash API | ||||
|  * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 | ||||
|  * | ||||
|  * The version of the OpenAPI document: 4.10.0-beta.1 | ||||
|  *  | ||||
|  * | ||||
|  * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 | ||||
|  * https://openapi-generator.tech
 | ||||
|  * Do not edit the class manually. | ||||
|  */ | ||||
| 
 | ||||
| import { exists, mapValues } from '../runtime'; | ||||
| /** | ||||
|  *  | ||||
|  * @export | ||||
|  * @interface ChangeProjectSchema | ||||
|  */ | ||||
| export interface ChangeProjectSchema { | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof ChangeProjectSchema | ||||
|      */ | ||||
|     newProjectId: string; | ||||
| } | ||||
| 
 | ||||
| export function ChangeProjectSchemaFromJSON(json: any): ChangeProjectSchema { | ||||
|     return ChangeProjectSchemaFromJSONTyped(json, false); | ||||
| } | ||||
| 
 | ||||
| export function ChangeProjectSchemaFromJSONTyped(json: any, ignoreDiscriminator: boolean): ChangeProjectSchema { | ||||
|     if ((json === undefined) || (json === null)) { | ||||
|         return json; | ||||
|     } | ||||
|     return { | ||||
|          | ||||
|         'newProjectId': json['newProjectId'], | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| export function ChangeProjectSchemaToJSON(value?: ChangeProjectSchema | null): any { | ||||
|     if (value === undefined) { | ||||
|         return undefined; | ||||
|     } | ||||
|     if (value === null) { | ||||
|         return null; | ||||
|     } | ||||
|     return { | ||||
|          | ||||
|         'newProjectId': value.newProjectId, | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										72
									
								
								frontend/src/openapi/models/ConstraintSchema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								frontend/src/openapi/models/ConstraintSchema.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,72 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| /** | ||||
|  * Unleash API | ||||
|  * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 | ||||
|  * | ||||
|  * The version of the OpenAPI document: 4.10.0-beta.1 | ||||
|  *  | ||||
|  * | ||||
|  * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 | ||||
|  * https://openapi-generator.tech
 | ||||
|  * Do not edit the class manually. | ||||
|  */ | ||||
| 
 | ||||
| import { exists, mapValues } from '../runtime'; | ||||
| /** | ||||
|  *  | ||||
|  * @export | ||||
|  * @interface ConstraintSchema | ||||
|  */ | ||||
| export interface ConstraintSchema { | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof ConstraintSchema | ||||
|      */ | ||||
|     contextName: string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof ConstraintSchema | ||||
|      */ | ||||
|     operator: string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {Array<string>} | ||||
|      * @memberof ConstraintSchema | ||||
|      */ | ||||
|     values?: Array<string>; | ||||
| } | ||||
| 
 | ||||
| export function ConstraintSchemaFromJSON(json: any): ConstraintSchema { | ||||
|     return ConstraintSchemaFromJSONTyped(json, false); | ||||
| } | ||||
| 
 | ||||
| export function ConstraintSchemaFromJSONTyped(json: any, ignoreDiscriminator: boolean): ConstraintSchema { | ||||
|     if ((json === undefined) || (json === null)) { | ||||
|         return json; | ||||
|     } | ||||
|     return { | ||||
|          | ||||
|         'contextName': json['contextName'], | ||||
|         'operator': json['operator'], | ||||
|         'values': !exists(json, 'values') ? undefined : json['values'], | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| export function ConstraintSchemaToJSON(value?: ConstraintSchema | null): any { | ||||
|     if (value === undefined) { | ||||
|         return undefined; | ||||
|     } | ||||
|     if (value === null) { | ||||
|         return null; | ||||
|     } | ||||
|     return { | ||||
|          | ||||
|         'contextName': value.contextName, | ||||
|         'operator': value.operator, | ||||
|         'values': value.values, | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										80
									
								
								frontend/src/openapi/models/CreateFeatureSchema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								frontend/src/openapi/models/CreateFeatureSchema.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,80 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| /** | ||||
|  * Unleash API | ||||
|  * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 | ||||
|  * | ||||
|  * The version of the OpenAPI document: 4.10.0-beta.1 | ||||
|  *  | ||||
|  * | ||||
|  * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 | ||||
|  * https://openapi-generator.tech
 | ||||
|  * Do not edit the class manually. | ||||
|  */ | ||||
| 
 | ||||
| import { exists, mapValues } from '../runtime'; | ||||
| /** | ||||
|  *  | ||||
|  * @export | ||||
|  * @interface CreateFeatureSchema | ||||
|  */ | ||||
| export interface CreateFeatureSchema { | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof CreateFeatureSchema | ||||
|      */ | ||||
|     name: string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof CreateFeatureSchema | ||||
|      */ | ||||
|     type?: string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof CreateFeatureSchema | ||||
|      */ | ||||
|     description?: string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {boolean} | ||||
|      * @memberof CreateFeatureSchema | ||||
|      */ | ||||
|     impressionData?: boolean; | ||||
| } | ||||
| 
 | ||||
| export function CreateFeatureSchemaFromJSON(json: any): CreateFeatureSchema { | ||||
|     return CreateFeatureSchemaFromJSONTyped(json, false); | ||||
| } | ||||
| 
 | ||||
| export function CreateFeatureSchemaFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateFeatureSchema { | ||||
|     if ((json === undefined) || (json === null)) { | ||||
|         return json; | ||||
|     } | ||||
|     return { | ||||
|          | ||||
|         'name': json['name'], | ||||
|         'type': !exists(json, 'type') ? undefined : json['type'], | ||||
|         'description': !exists(json, 'description') ? undefined : json['description'], | ||||
|         'impressionData': !exists(json, 'impressionData') ? undefined : json['impressionData'], | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| export function CreateFeatureSchemaToJSON(value?: CreateFeatureSchema | null): any { | ||||
|     if (value === undefined) { | ||||
|         return undefined; | ||||
|     } | ||||
|     if (value === null) { | ||||
|         return null; | ||||
|     } | ||||
|     return { | ||||
|          | ||||
|         'name': value.name, | ||||
|         'type': value.type, | ||||
|         'description': value.description, | ||||
|         'impressionData': value.impressionData, | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										149
									
								
								frontend/src/openapi/models/FeatureSchema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								frontend/src/openapi/models/FeatureSchema.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,149 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| /** | ||||
|  * Unleash API | ||||
|  * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 | ||||
|  * | ||||
|  * The version of the OpenAPI document: 4.10.0-beta.1 | ||||
|  *  | ||||
|  * | ||||
|  * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 | ||||
|  * https://openapi-generator.tech
 | ||||
|  * Do not edit the class manually. | ||||
|  */ | ||||
| 
 | ||||
| import { exists, mapValues } from '../runtime'; | ||||
| import { | ||||
|     StrategySchema, | ||||
|     StrategySchemaFromJSON, | ||||
|     StrategySchemaFromJSONTyped, | ||||
|     StrategySchemaToJSON, | ||||
| } from './StrategySchema'; | ||||
| import { | ||||
|     VariantSchema, | ||||
|     VariantSchemaFromJSON, | ||||
|     VariantSchemaFromJSONTyped, | ||||
|     VariantSchemaToJSON, | ||||
| } from './VariantSchema'; | ||||
| 
 | ||||
| /** | ||||
|  *  | ||||
|  * @export | ||||
|  * @interface FeatureSchema | ||||
|  */ | ||||
| export interface FeatureSchema { | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof FeatureSchema | ||||
|      */ | ||||
|     name: string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof FeatureSchema | ||||
|      */ | ||||
|     type?: string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof FeatureSchema | ||||
|      */ | ||||
|     description?: string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof FeatureSchema | ||||
|      */ | ||||
|     project: string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {boolean} | ||||
|      * @memberof FeatureSchema | ||||
|      */ | ||||
|     enabled?: boolean; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {boolean} | ||||
|      * @memberof FeatureSchema | ||||
|      */ | ||||
|     stale?: boolean; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {boolean} | ||||
|      * @memberof FeatureSchema | ||||
|      */ | ||||
|     impressionData?: boolean; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {Date} | ||||
|      * @memberof FeatureSchema | ||||
|      */ | ||||
|     createdAt?: Date | null; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {Date} | ||||
|      * @memberof FeatureSchema | ||||
|      */ | ||||
|     lastSeenAt?: Date | null; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {Array<StrategySchema>} | ||||
|      * @memberof FeatureSchema | ||||
|      */ | ||||
|     strategies?: Array<StrategySchema>; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {Array<VariantSchema>} | ||||
|      * @memberof FeatureSchema | ||||
|      */ | ||||
|     variants?: Array<VariantSchema>; | ||||
| } | ||||
| 
 | ||||
| export function FeatureSchemaFromJSON(json: any): FeatureSchema { | ||||
|     return FeatureSchemaFromJSONTyped(json, false); | ||||
| } | ||||
| 
 | ||||
| export function FeatureSchemaFromJSONTyped(json: any, ignoreDiscriminator: boolean): FeatureSchema { | ||||
|     if ((json === undefined) || (json === null)) { | ||||
|         return json; | ||||
|     } | ||||
|     return { | ||||
|          | ||||
|         'name': json['name'], | ||||
|         'type': !exists(json, 'type') ? undefined : json['type'], | ||||
|         'description': !exists(json, 'description') ? undefined : json['description'], | ||||
|         'project': json['project'], | ||||
|         'enabled': !exists(json, 'enabled') ? undefined : json['enabled'], | ||||
|         'stale': !exists(json, 'stale') ? undefined : json['stale'], | ||||
|         'impressionData': !exists(json, 'impressionData') ? undefined : json['impressionData'], | ||||
|         'createdAt': !exists(json, 'createdAt') ? undefined : (json['createdAt'] === null ? null : new Date(json['createdAt'])), | ||||
|         'lastSeenAt': !exists(json, 'lastSeenAt') ? undefined : (json['lastSeenAt'] === null ? null : new Date(json['lastSeenAt'])), | ||||
|         'strategies': !exists(json, 'strategies') ? undefined : ((json['strategies'] as Array<any>).map(StrategySchemaFromJSON)), | ||||
|         'variants': !exists(json, 'variants') ? undefined : ((json['variants'] as Array<any>).map(VariantSchemaFromJSON)), | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| export function FeatureSchemaToJSON(value?: FeatureSchema | null): any { | ||||
|     if (value === undefined) { | ||||
|         return undefined; | ||||
|     } | ||||
|     if (value === null) { | ||||
|         return null; | ||||
|     } | ||||
|     return { | ||||
|          | ||||
|         'name': value.name, | ||||
|         'type': value.type, | ||||
|         'description': value.description, | ||||
|         'project': value.project, | ||||
|         'enabled': value.enabled, | ||||
|         'stale': value.stale, | ||||
|         'impressionData': value.impressionData, | ||||
|         'createdAt': value.createdAt === undefined ? undefined : (value.createdAt === null ? null : value.createdAt.toISOString().substr(0,10)), | ||||
|         'lastSeenAt': value.lastSeenAt === undefined ? undefined : (value.lastSeenAt === null ? null : value.lastSeenAt.toISOString().substr(0,10)), | ||||
|         'strategies': value.strategies === undefined ? undefined : ((value.strategies as Array<any>).map(StrategySchemaToJSON)), | ||||
|         'variants': value.variants === undefined ? undefined : ((value.variants as Array<any>).map(VariantSchemaToJSON)), | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										71
									
								
								frontend/src/openapi/models/FeaturesSchema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								frontend/src/openapi/models/FeaturesSchema.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| /** | ||||
|  * Unleash API | ||||
|  * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 | ||||
|  * | ||||
|  * The version of the OpenAPI document: 4.10.0-beta.1 | ||||
|  *  | ||||
|  * | ||||
|  * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 | ||||
|  * https://openapi-generator.tech
 | ||||
|  * Do not edit the class manually. | ||||
|  */ | ||||
| 
 | ||||
| import { exists, mapValues } from '../runtime'; | ||||
| import { | ||||
|     FeatureSchema, | ||||
|     FeatureSchemaFromJSON, | ||||
|     FeatureSchemaFromJSONTyped, | ||||
|     FeatureSchemaToJSON, | ||||
| } from './FeatureSchema'; | ||||
| 
 | ||||
| /** | ||||
|  *  | ||||
|  * @export | ||||
|  * @interface FeaturesSchema | ||||
|  */ | ||||
| export interface FeaturesSchema { | ||||
|     /** | ||||
|      *  | ||||
|      * @type {number} | ||||
|      * @memberof FeaturesSchema | ||||
|      */ | ||||
|     version: number; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {Array<FeatureSchema>} | ||||
|      * @memberof FeaturesSchema | ||||
|      */ | ||||
|     features: Array<FeatureSchema>; | ||||
| } | ||||
| 
 | ||||
| export function FeaturesSchemaFromJSON(json: any): FeaturesSchema { | ||||
|     return FeaturesSchemaFromJSONTyped(json, false); | ||||
| } | ||||
| 
 | ||||
| export function FeaturesSchemaFromJSONTyped(json: any, ignoreDiscriminator: boolean): FeaturesSchema { | ||||
|     if ((json === undefined) || (json === null)) { | ||||
|         return json; | ||||
|     } | ||||
|     return { | ||||
|          | ||||
|         'version': json['version'], | ||||
|         'features': ((json['features'] as Array<any>).map(FeatureSchemaFromJSON)), | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| export function FeaturesSchemaToJSON(value?: FeaturesSchema | null): any { | ||||
|     if (value === undefined) { | ||||
|         return undefined; | ||||
|     } | ||||
|     if (value === null) { | ||||
|         return null; | ||||
|     } | ||||
|     return { | ||||
|          | ||||
|         'version': value.version, | ||||
|         'features': ((value.features as Array<any>).map(FeatureSchemaToJSON)), | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										64
									
								
								frontend/src/openapi/models/OverrideSchema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								frontend/src/openapi/models/OverrideSchema.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| /** | ||||
|  * Unleash API | ||||
|  * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 | ||||
|  * | ||||
|  * The version of the OpenAPI document: 4.10.0-beta.1 | ||||
|  *  | ||||
|  * | ||||
|  * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 | ||||
|  * https://openapi-generator.tech
 | ||||
|  * Do not edit the class manually. | ||||
|  */ | ||||
| 
 | ||||
| import { exists, mapValues } from '../runtime'; | ||||
| /** | ||||
|  *  | ||||
|  * @export | ||||
|  * @interface OverrideSchema | ||||
|  */ | ||||
| export interface OverrideSchema { | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof OverrideSchema | ||||
|      */ | ||||
|     contextName: string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {Array<string>} | ||||
|      * @memberof OverrideSchema | ||||
|      */ | ||||
|     values: Array<string>; | ||||
| } | ||||
| 
 | ||||
| export function OverrideSchemaFromJSON(json: any): OverrideSchema { | ||||
|     return OverrideSchemaFromJSONTyped(json, false); | ||||
| } | ||||
| 
 | ||||
| export function OverrideSchemaFromJSONTyped(json: any, ignoreDiscriminator: boolean): OverrideSchema { | ||||
|     if ((json === undefined) || (json === null)) { | ||||
|         return json; | ||||
|     } | ||||
|     return { | ||||
|          | ||||
|         'contextName': json['contextName'], | ||||
|         'values': json['values'], | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| export function OverrideSchemaToJSON(value?: OverrideSchema | null): any { | ||||
|     if (value === undefined) { | ||||
|         return undefined; | ||||
|     } | ||||
|     if (value === null) { | ||||
|         return null; | ||||
|     } | ||||
|     return { | ||||
|          | ||||
|         'contextName': value.contextName, | ||||
|         'values': value.values, | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										87
									
								
								frontend/src/openapi/models/StrategySchema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								frontend/src/openapi/models/StrategySchema.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| /** | ||||
|  * Unleash API | ||||
|  * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 | ||||
|  * | ||||
|  * The version of the OpenAPI document: 4.10.0-beta.1 | ||||
|  *  | ||||
|  * | ||||
|  * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 | ||||
|  * https://openapi-generator.tech
 | ||||
|  * Do not edit the class manually. | ||||
|  */ | ||||
| 
 | ||||
| import { exists, mapValues } from '../runtime'; | ||||
| import { | ||||
|     ConstraintSchema, | ||||
|     ConstraintSchemaFromJSON, | ||||
|     ConstraintSchemaFromJSONTyped, | ||||
|     ConstraintSchemaToJSON, | ||||
| } from './ConstraintSchema'; | ||||
| 
 | ||||
| /** | ||||
|  *  | ||||
|  * @export | ||||
|  * @interface StrategySchema | ||||
|  */ | ||||
| export interface StrategySchema { | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof StrategySchema | ||||
|      */ | ||||
|     id: string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof StrategySchema | ||||
|      */ | ||||
|     name: string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {Array<ConstraintSchema>} | ||||
|      * @memberof StrategySchema | ||||
|      */ | ||||
|     constraints: Array<ConstraintSchema>; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {object} | ||||
|      * @memberof StrategySchema | ||||
|      */ | ||||
|     parameters: object; | ||||
| } | ||||
| 
 | ||||
| export function StrategySchemaFromJSON(json: any): StrategySchema { | ||||
|     return StrategySchemaFromJSONTyped(json, false); | ||||
| } | ||||
| 
 | ||||
| export function StrategySchemaFromJSONTyped(json: any, ignoreDiscriminator: boolean): StrategySchema { | ||||
|     if ((json === undefined) || (json === null)) { | ||||
|         return json; | ||||
|     } | ||||
|     return { | ||||
|          | ||||
|         'id': json['id'], | ||||
|         'name': json['name'], | ||||
|         'constraints': ((json['constraints'] as Array<any>).map(ConstraintSchemaFromJSON)), | ||||
|         'parameters': json['parameters'], | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| export function StrategySchemaToJSON(value?: StrategySchema | null): any { | ||||
|     if (value === undefined) { | ||||
|         return undefined; | ||||
|     } | ||||
|     if (value === null) { | ||||
|         return null; | ||||
|     } | ||||
|     return { | ||||
|          | ||||
|         'id': value.id, | ||||
|         'name': value.name, | ||||
|         'constraints': ((value.constraints as Array<any>).map(ConstraintSchemaToJSON)), | ||||
|         'parameters': value.parameters, | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										103
									
								
								frontend/src/openapi/models/VariantSchema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								frontend/src/openapi/models/VariantSchema.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| /** | ||||
|  * Unleash API | ||||
|  * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 | ||||
|  * | ||||
|  * The version of the OpenAPI document: 4.10.0-beta.1 | ||||
|  *  | ||||
|  * | ||||
|  * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 | ||||
|  * https://openapi-generator.tech
 | ||||
|  * Do not edit the class manually. | ||||
|  */ | ||||
| 
 | ||||
| import { exists, mapValues } from '../runtime'; | ||||
| import { | ||||
|     OverrideSchema, | ||||
|     OverrideSchemaFromJSON, | ||||
|     OverrideSchemaFromJSONTyped, | ||||
|     OverrideSchemaToJSON, | ||||
| } from './OverrideSchema'; | ||||
| 
 | ||||
| /** | ||||
|  *  | ||||
|  * @export | ||||
|  * @interface VariantSchema | ||||
|  */ | ||||
| export interface VariantSchema { | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof VariantSchema | ||||
|      */ | ||||
|     name: string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {number} | ||||
|      * @memberof VariantSchema | ||||
|      */ | ||||
|     weight: number; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof VariantSchema | ||||
|      */ | ||||
|     weightType: string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof VariantSchema | ||||
|      */ | ||||
|     stickiness: string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {object} | ||||
|      * @memberof VariantSchema | ||||
|      */ | ||||
|     payload?: object; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {Array<OverrideSchema>} | ||||
|      * @memberof VariantSchema | ||||
|      */ | ||||
|     overrides: Array<OverrideSchema>; | ||||
| } | ||||
| 
 | ||||
| export function VariantSchemaFromJSON(json: any): VariantSchema { | ||||
|     return VariantSchemaFromJSONTyped(json, false); | ||||
| } | ||||
| 
 | ||||
| export function VariantSchemaFromJSONTyped(json: any, ignoreDiscriminator: boolean): VariantSchema { | ||||
|     if ((json === undefined) || (json === null)) { | ||||
|         return json; | ||||
|     } | ||||
|     return { | ||||
|          | ||||
|         'name': json['name'], | ||||
|         'weight': json['weight'], | ||||
|         'weightType': json['weightType'], | ||||
|         'stickiness': json['stickiness'], | ||||
|         'payload': !exists(json, 'payload') ? undefined : json['payload'], | ||||
|         'overrides': ((json['overrides'] as Array<any>).map(OverrideSchemaFromJSON)), | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| export function VariantSchemaToJSON(value?: VariantSchema | null): any { | ||||
|     if (value === undefined) { | ||||
|         return undefined; | ||||
|     } | ||||
|     if (value === null) { | ||||
|         return null; | ||||
|     } | ||||
|     return { | ||||
|          | ||||
|         'name': value.name, | ||||
|         'weight': value.weight, | ||||
|         'weightType': value.weightType, | ||||
|         'stickiness': value.stickiness, | ||||
|         'payload': value.payload, | ||||
|         'overrides': ((value.overrides as Array<any>).map(OverrideSchemaToJSON)), | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										10
									
								
								frontend/src/openapi/models/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								frontend/src/openapi/models/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| export * from './ChangeProjectSchema'; | ||||
| export * from './ConstraintSchema'; | ||||
| export * from './CreateFeatureSchema'; | ||||
| export * from './FeatureSchema'; | ||||
| export * from './FeaturesSchema'; | ||||
| export * from './OverrideSchema'; | ||||
| export * from './StrategySchema'; | ||||
| export * from './VariantSchema'; | ||||
							
								
								
									
										320
									
								
								frontend/src/openapi/runtime.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										320
									
								
								frontend/src/openapi/runtime.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,320 @@ | ||||
| /* tslint:disable */ | ||||
| /* eslint-disable */ | ||||
| /** | ||||
|  * Unleash API | ||||
|  * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 | ||||
|  * | ||||
|  * The version of the OpenAPI document: 4.10.0-beta.1 | ||||
|  *  | ||||
|  * | ||||
|  * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 | ||||
|  * https://openapi-generator.tech
 | ||||
|  * Do not edit the class manually. | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| export const BASE_PATH = "http://localhost:4242".replace(/\/+$/, ""); | ||||
| 
 | ||||
| const isBlob = (value: any) => typeof Blob !== 'undefined' && value instanceof Blob; | ||||
| 
 | ||||
| /** | ||||
|  * This is the base class for all generated API classes. | ||||
|  */ | ||||
| export class BaseAPI { | ||||
| 
 | ||||
|     private middleware: Middleware[]; | ||||
| 
 | ||||
|     constructor(protected configuration = new Configuration()) { | ||||
|         this.middleware = configuration.middleware; | ||||
|     } | ||||
| 
 | ||||
|     withMiddleware<T extends BaseAPI>(this: T, ...middlewares: Middleware[]) { | ||||
|         const next = this.clone<T>(); | ||||
|         next.middleware = next.middleware.concat(...middlewares); | ||||
|         return next; | ||||
|     } | ||||
| 
 | ||||
|     withPreMiddleware<T extends BaseAPI>(this: T, ...preMiddlewares: Array<Middleware['pre']>) { | ||||
|         const middlewares = preMiddlewares.map((pre) => ({ pre })); | ||||
|         return this.withMiddleware<T>(...middlewares); | ||||
|     } | ||||
| 
 | ||||
|     withPostMiddleware<T extends BaseAPI>(this: T, ...postMiddlewares: Array<Middleware['post']>) { | ||||
|         const middlewares = postMiddlewares.map((post) => ({ post })); | ||||
|         return this.withMiddleware<T>(...middlewares); | ||||
|     } | ||||
| 
 | ||||
|     protected async request(context: RequestOpts, initOverrides?: RequestInit): Promise<Response> { | ||||
|         const { url, init } = this.createFetchParams(context, initOverrides); | ||||
|         const response = await this.fetchApi(url, init); | ||||
|         if (response.status >= 200 && response.status < 300) { | ||||
|             return response; | ||||
|         } | ||||
|         throw response; | ||||
|     } | ||||
| 
 | ||||
|     private createFetchParams(context: RequestOpts, initOverrides?: RequestInit) { | ||||
|         let url = this.configuration.basePath + context.path; | ||||
|         if (context.query !== undefined && Object.keys(context.query).length !== 0) { | ||||
|             // only add the querystring to the URL if there are query parameters.
 | ||||
|             // this is done to avoid urls ending with a "?" character which buggy webservers
 | ||||
|             // do not handle correctly sometimes.
 | ||||
|             url += '?' + this.configuration.queryParamsStringify(context.query); | ||||
|         } | ||||
|         const body = ((typeof FormData !== "undefined" && context.body instanceof FormData) || context.body instanceof URLSearchParams || isBlob(context.body)) | ||||
|         ? context.body | ||||
|         : JSON.stringify(context.body); | ||||
| 
 | ||||
|         const headers = Object.assign({}, this.configuration.headers, context.headers); | ||||
|         const init = { | ||||
|             method: context.method, | ||||
|             headers: headers, | ||||
|             body, | ||||
|             credentials: this.configuration.credentials, | ||||
|             ...initOverrides | ||||
|         }; | ||||
|         return { url, init }; | ||||
|     } | ||||
| 
 | ||||
|     private fetchApi = async (url: string, init: RequestInit) => { | ||||
|         let fetchParams = { url, init }; | ||||
|         for (const middleware of this.middleware) { | ||||
|             if (middleware.pre) { | ||||
|                 fetchParams = await middleware.pre({ | ||||
|                     fetch: this.fetchApi, | ||||
|                     ...fetchParams, | ||||
|                 }) || fetchParams; | ||||
|             } | ||||
|         } | ||||
|         let response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); | ||||
|         for (const middleware of this.middleware) { | ||||
|             if (middleware.post) { | ||||
|                 response = await middleware.post({ | ||||
|                     fetch: this.fetchApi, | ||||
|                     url: fetchParams.url, | ||||
|                     init: fetchParams.init, | ||||
|                     response: response.clone(), | ||||
|                 }) || response; | ||||
|             } | ||||
|         } | ||||
|         return response; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Create a shallow clone of `this` by constructing a new instance | ||||
|      * and then shallow cloning data members. | ||||
|      */ | ||||
|     private clone<T extends BaseAPI>(this: T): T { | ||||
|         const constructor = this.constructor as any; | ||||
|         const next = new constructor(this.configuration); | ||||
|         next.middleware = this.middleware.slice(); | ||||
|         return next; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| export class RequiredError extends Error { | ||||
|     name: "RequiredError" = "RequiredError"; | ||||
|     constructor(public field: string, msg?: string) { | ||||
|         super(msg); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export const COLLECTION_FORMATS = { | ||||
|     csv: ",", | ||||
|     ssv: " ", | ||||
|     tsv: "\t", | ||||
|     pipes: "|", | ||||
| }; | ||||
| 
 | ||||
| export type FetchAPI = GlobalFetch['fetch']; | ||||
| 
 | ||||
| export interface ConfigurationParameters { | ||||
|     basePath?: string; // override base path
 | ||||
|     fetchApi?: FetchAPI; // override for fetch implementation
 | ||||
|     middleware?: Middleware[]; // middleware to apply before/after fetch requests
 | ||||
|     queryParamsStringify?: (params: HTTPQuery) => string; // stringify function for query strings
 | ||||
|     username?: string; // parameter for basic security
 | ||||
|     password?: string; // parameter for basic security
 | ||||
|     apiKey?: string | ((name: string) => string); // parameter for apiKey security
 | ||||
|     accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string | Promise<string>); // parameter for oauth2 security
 | ||||
|     headers?: HTTPHeaders; //header params we want to use on every request
 | ||||
|     credentials?: RequestCredentials; //value for the credentials param we want to use on each request
 | ||||
| } | ||||
| 
 | ||||
| export class Configuration { | ||||
|     constructor(private configuration: ConfigurationParameters = {}) {} | ||||
| 
 | ||||
|     get basePath(): string { | ||||
|         return this.configuration.basePath != null ? this.configuration.basePath : BASE_PATH; | ||||
|     } | ||||
| 
 | ||||
|     get fetchApi(): FetchAPI | undefined { | ||||
|         return this.configuration.fetchApi; | ||||
|     } | ||||
| 
 | ||||
|     get middleware(): Middleware[] { | ||||
|         return this.configuration.middleware || []; | ||||
|     } | ||||
| 
 | ||||
|     get queryParamsStringify(): (params: HTTPQuery) => string { | ||||
|         return this.configuration.queryParamsStringify || querystring; | ||||
|     } | ||||
| 
 | ||||
|     get username(): string | undefined { | ||||
|         return this.configuration.username; | ||||
|     } | ||||
| 
 | ||||
|     get password(): string | undefined { | ||||
|         return this.configuration.password; | ||||
|     } | ||||
| 
 | ||||
|     get apiKey(): ((name: string) => string) | undefined { | ||||
|         const apiKey = this.configuration.apiKey; | ||||
|         if (apiKey) { | ||||
|             return typeof apiKey === 'function' ? apiKey : () => apiKey; | ||||
|         } | ||||
|         return undefined; | ||||
|     } | ||||
| 
 | ||||
|     get accessToken(): ((name?: string, scopes?: string[]) => string | Promise<string>) | undefined { | ||||
|         const accessToken = this.configuration.accessToken; | ||||
|         if (accessToken) { | ||||
|             return typeof accessToken === 'function' ? accessToken : async () => accessToken; | ||||
|         } | ||||
|         return undefined; | ||||
|     } | ||||
| 
 | ||||
|     get headers(): HTTPHeaders | undefined { | ||||
|         return this.configuration.headers; | ||||
|     } | ||||
| 
 | ||||
|     get credentials(): RequestCredentials | undefined { | ||||
|         return this.configuration.credentials; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export type Json = any; | ||||
| export type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD'; | ||||
| export type HTTPHeaders = { [key: string]: string }; | ||||
| export type HTTPQuery = { [key: string]: string | number | null | boolean | Array<string | number | null | boolean> | HTTPQuery }; | ||||
| export type HTTPBody = Json | FormData | URLSearchParams; | ||||
| export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original'; | ||||
| 
 | ||||
| export interface FetchParams { | ||||
|     url: string; | ||||
|     init: RequestInit; | ||||
| } | ||||
| 
 | ||||
| export interface RequestOpts { | ||||
|     path: string; | ||||
|     method: HTTPMethod; | ||||
|     headers: HTTPHeaders; | ||||
|     query?: HTTPQuery; | ||||
|     body?: HTTPBody; | ||||
| } | ||||
| 
 | ||||
| export function exists(json: any, key: string) { | ||||
|     const value = json[key]; | ||||
|     return value !== null && value !== undefined; | ||||
| } | ||||
| 
 | ||||
| export function querystring(params: HTTPQuery, prefix: string = ''): string { | ||||
|     return Object.keys(params) | ||||
|         .map((key) => { | ||||
|             const fullKey = prefix + (prefix.length ? `[${key}]` : key); | ||||
|             const value = params[key]; | ||||
|             if (value instanceof Array) { | ||||
|                 const multiValue = value.map(singleValue => encodeURIComponent(String(singleValue))) | ||||
|                     .join(`&${encodeURIComponent(fullKey)}=`); | ||||
|                 return `${encodeURIComponent(fullKey)}=${multiValue}`; | ||||
|             } | ||||
|             if (value instanceof Date) { | ||||
|                 return `${encodeURIComponent(fullKey)}=${encodeURIComponent(value.toISOString())}`; | ||||
|             } | ||||
|             if (value instanceof Object) { | ||||
|                 return querystring(value as HTTPQuery, fullKey); | ||||
|             } | ||||
|             return `${encodeURIComponent(fullKey)}=${encodeURIComponent(String(value))}`; | ||||
|         }) | ||||
|         .filter(part => part.length > 0) | ||||
|         .join('&'); | ||||
| } | ||||
| 
 | ||||
| export function mapValues(data: any, fn: (item: any) => any) { | ||||
|   return Object.keys(data).reduce( | ||||
|     (acc, key) => ({ ...acc, [key]: fn(data[key]) }), | ||||
|     {} | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export function canConsumeForm(consumes: Consume[]): boolean { | ||||
|     for (const consume of consumes) { | ||||
|         if ('multipart/form-data' === consume.contentType) { | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| export interface Consume { | ||||
|     contentType: string | ||||
| } | ||||
| 
 | ||||
| export interface RequestContext { | ||||
|     fetch: FetchAPI; | ||||
|     url: string; | ||||
|     init: RequestInit; | ||||
| } | ||||
| 
 | ||||
| export interface ResponseContext { | ||||
|     fetch: FetchAPI; | ||||
|     url: string; | ||||
|     init: RequestInit; | ||||
|     response: Response; | ||||
| } | ||||
| 
 | ||||
| export interface Middleware { | ||||
|     pre?(context: RequestContext): Promise<FetchParams | void>; | ||||
|     post?(context: ResponseContext): Promise<Response | void>; | ||||
| } | ||||
| 
 | ||||
| export interface ApiResponse<T> { | ||||
|     raw: Response; | ||||
|     value(): Promise<T>; | ||||
| } | ||||
| 
 | ||||
| export interface ResponseTransformer<T> { | ||||
|     (json: any): T; | ||||
| } | ||||
| 
 | ||||
| export class JSONApiResponse<T> { | ||||
|     constructor(public raw: Response, private transformer: ResponseTransformer<T> = (jsonValue: any) => jsonValue) {} | ||||
| 
 | ||||
|     async value(): Promise<T> { | ||||
|         return this.transformer(await this.raw.json()); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export class VoidApiResponse { | ||||
|     constructor(public raw: Response) {} | ||||
| 
 | ||||
|     async value(): Promise<void> { | ||||
|         return undefined; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export class BlobApiResponse { | ||||
|     constructor(public raw: Response) {} | ||||
| 
 | ||||
|     async value(): Promise<Blob> { | ||||
|         return await this.raw.blob(); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| export class TextApiResponse { | ||||
|     constructor(public raw: Response) {} | ||||
| 
 | ||||
|     async value(): Promise<string> { | ||||
|         return await this.raw.text(); | ||||
|     }; | ||||
| } | ||||
							
								
								
									
										3
									
								
								frontend/src/types/global-fetch.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								frontend/src/types/global-fetch.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| // Add missing GlobalFetch declaration for the OpenAPI bindings.
 | ||||
| // https://github.com/apollographql/apollo-link/issues/1131#issuecomment-526109609
 | ||||
| declare type GlobalFetch = WindowOrWorkerGlobalScope; | ||||
							
								
								
									
										12
									
								
								frontend/src/utils/openapiClient.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								frontend/src/utils/openapiClient.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| import { Configuration, AdminApi } from 'openapi'; | ||||
| import { getBasePath } from 'utils/formatPath'; | ||||
| 
 | ||||
| const createAdminApi = (): AdminApi => { | ||||
|     return new AdminApi( | ||||
|         new Configuration({ | ||||
|             basePath: getBasePath(), | ||||
|         }) | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| export const openApiAdmin = createAdminApi(); | ||||
| @ -1502,6 +1502,29 @@ | ||||
|     outvariant "^1.2.1" | ||||
|     strict-event-emitter "^0.2.0" | ||||
| 
 | ||||
| "@nestjs/common@8.2.6": | ||||
|   version "8.2.6" | ||||
|   resolved "https://registry.yarnpkg.com/@nestjs/common/-/common-8.2.6.tgz#34cd5cc44082d3525c56c95db42ca0e5277b7d85" | ||||
|   integrity sha512-flLYSXunxcKyjbYddrhwbc49uE705MxBt85rS3mHyhDbAIPSGGeZEqME44YyAzCg1NTfJSNe7ztmOce5kNkb9A== | ||||
|   dependencies: | ||||
|     axios "0.24.0" | ||||
|     iterare "1.2.1" | ||||
|     tslib "2.3.1" | ||||
|     uuid "8.3.2" | ||||
| 
 | ||||
| "@nestjs/core@8.2.6": | ||||
|   version "8.2.6" | ||||
|   resolved "https://registry.yarnpkg.com/@nestjs/core/-/core-8.2.6.tgz#08eb38203fb01a828227ea25972d38bfef5c818f" | ||||
|   integrity sha512-NwPcEIMmCsucs3QaDlQvkoU1FlFM2wm/WjaqLQhkSoIEmAR1gNtBo88f5io5cpMwCo1k5xYhqGlaSl6TfngwWQ== | ||||
|   dependencies: | ||||
|     "@nuxtjs/opencollective" "0.3.2" | ||||
|     fast-safe-stringify "2.1.1" | ||||
|     iterare "1.2.1" | ||||
|     object-hash "2.2.0" | ||||
|     path-to-regexp "3.2.0" | ||||
|     tslib "2.3.1" | ||||
|     uuid "8.3.2" | ||||
| 
 | ||||
| "@nodelib/fs.scandir@2.1.5": | ||||
|   version "2.1.5" | ||||
|   resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" | ||||
| @ -1523,11 +1546,41 @@ | ||||
|     "@nodelib/fs.scandir" "2.1.5" | ||||
|     fastq "^1.6.0" | ||||
| 
 | ||||
| "@nuxtjs/opencollective@0.3.2": | ||||
|   version "0.3.2" | ||||
|   resolved "https://registry.yarnpkg.com/@nuxtjs/opencollective/-/opencollective-0.3.2.tgz#620ce1044f7ac77185e825e1936115bb38e2681c" | ||||
|   integrity sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA== | ||||
|   dependencies: | ||||
|     chalk "^4.1.0" | ||||
|     consola "^2.15.0" | ||||
|     node-fetch "^2.6.1" | ||||
| 
 | ||||
| "@open-draft/until@^1.0.3": | ||||
|   version "1.0.3" | ||||
|   resolved "https://registry.yarnpkg.com/@open-draft/until/-/until-1.0.3.tgz#db9cc719191a62e7d9200f6e7bab21c5b848adca" | ||||
|   integrity sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q== | ||||
| 
 | ||||
| "@openapitools/openapi-generator-cli@^2.4.26": | ||||
|   version "2.4.26" | ||||
|   resolved "https://registry.yarnpkg.com/@openapitools/openapi-generator-cli/-/openapi-generator-cli-2.4.26.tgz#67622fc41c258aeae3ff074cd92772978e03484f" | ||||
|   integrity sha512-O42H9q1HWGoIpcpMaUu318b6bmOgcjP3MieHwOrFdoG3KyttceBGlbLf9Kbf7WM91WSNCDXum7cnEKASuoGjAg== | ||||
|   dependencies: | ||||
|     "@nestjs/common" "8.2.6" | ||||
|     "@nestjs/core" "8.2.6" | ||||
|     "@nuxtjs/opencollective" "0.3.2" | ||||
|     chalk "4.1.2" | ||||
|     commander "8.3.0" | ||||
|     compare-versions "3.6.0" | ||||
|     concurrently "6.5.1" | ||||
|     console.table "0.10.0" | ||||
|     fs-extra "10.0.0" | ||||
|     glob "7.1.6" | ||||
|     inquirer "8.2.0" | ||||
|     lodash "4.17.21" | ||||
|     reflect-metadata "0.1.13" | ||||
|     rxjs "7.5.2" | ||||
|     tslib "2.0.3" | ||||
| 
 | ||||
| "@pmmmwh/react-refresh-webpack-plugin@^0.5.3": | ||||
|   version "0.5.5" | ||||
|   resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.5.tgz#e77aac783bd079f548daa0a7f080ab5b5a9741ca" | ||||
| @ -2807,6 +2860,13 @@ axe-core@^4.3.5: | ||||
|   resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.1.tgz#7dbdc25989298f9ad006645cd396782443757413" | ||||
|   integrity sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw== | ||||
| 
 | ||||
| axios@0.24.0: | ||||
|   version "0.24.0" | ||||
|   resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6" | ||||
|   integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA== | ||||
|   dependencies: | ||||
|     follow-redirects "^1.14.4" | ||||
| 
 | ||||
| axobject-query@^2.2.0: | ||||
|   version "2.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" | ||||
| @ -3192,6 +3252,14 @@ chalk@4.1.1: | ||||
|     ansi-styles "^4.1.0" | ||||
|     supports-color "^7.1.0" | ||||
| 
 | ||||
| chalk@4.1.2, chalk@^4.0.2, chalk@^4.1.1, chalk@^4.1.2: | ||||
|   version "4.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" | ||||
|   integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== | ||||
|   dependencies: | ||||
|     ansi-styles "^4.1.0" | ||||
|     supports-color "^7.1.0" | ||||
| 
 | ||||
| chalk@^2.0.0, chalk@^2.4.1: | ||||
|   version "2.4.2" | ||||
|   resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" | ||||
| @ -3209,10 +3277,10 @@ chalk@^3.0.0: | ||||
|     ansi-styles "^4.1.0" | ||||
|     supports-color "^7.1.0" | ||||
| 
 | ||||
| chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: | ||||
|   version "4.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" | ||||
|   integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== | ||||
| chalk@^4.0.0, chalk@^4.1.0: | ||||
|   version "4.1.0" | ||||
|   resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz" | ||||
|   integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== | ||||
|   dependencies: | ||||
|     ansi-styles "^4.1.0" | ||||
|     supports-color "^7.1.0" | ||||
| @ -3422,6 +3490,11 @@ combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: | ||||
|   dependencies: | ||||
|     delayed-stream "~1.0.0" | ||||
| 
 | ||||
| commander@8.3.0, commander@^8.3.0: | ||||
|   version "8.3.0" | ||||
|   resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" | ||||
|   integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== | ||||
| 
 | ||||
| commander@^2.20.0: | ||||
|   version "2.20.3" | ||||
|   resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" | ||||
| @ -3437,11 +3510,6 @@ commander@^7.2.0: | ||||
|   resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" | ||||
|   integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== | ||||
| 
 | ||||
| commander@^8.3.0: | ||||
|   version "8.3.0" | ||||
|   resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" | ||||
|   integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== | ||||
| 
 | ||||
| common-path-prefix@^3.0.0: | ||||
|   version "3.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" | ||||
| @ -3457,6 +3525,11 @@ commondir@^1.0.1: | ||||
|   resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" | ||||
|   integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= | ||||
| 
 | ||||
| compare-versions@3.6.0: | ||||
|   version "3.6.0" | ||||
|   resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62" | ||||
|   integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== | ||||
| 
 | ||||
| compressible@~2.0.16: | ||||
|   version "2.0.18" | ||||
|   resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" | ||||
| @ -3482,6 +3555,20 @@ concat-map@0.0.1: | ||||
|   resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" | ||||
|   integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= | ||||
| 
 | ||||
| concurrently@6.5.1: | ||||
|   version "6.5.1" | ||||
|   resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-6.5.1.tgz#4518c67f7ac680cf5c34d5adf399a2a2047edc8c" | ||||
|   integrity sha512-FlSwNpGjWQfRwPLXvJ/OgysbBxPkWpiVjy1042b0U7on7S7qwwMIILRj7WTN1mTgqa582bG6NFuScOoh6Zgdag== | ||||
|   dependencies: | ||||
|     chalk "^4.1.0" | ||||
|     date-fns "^2.16.1" | ||||
|     lodash "^4.17.21" | ||||
|     rxjs "^6.6.3" | ||||
|     spawn-command "^0.0.2-1" | ||||
|     supports-color "^8.1.0" | ||||
|     tree-kill "^1.2.2" | ||||
|     yargs "^16.2.0" | ||||
| 
 | ||||
| confusing-browser-globals@^1.0.11: | ||||
|   version "1.0.11" | ||||
|   resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" | ||||
| @ -3492,6 +3579,18 @@ connect-history-api-fallback@^1.6.0: | ||||
|   resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" | ||||
|   integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== | ||||
| 
 | ||||
| consola@^2.15.0: | ||||
|   version "2.15.3" | ||||
|   resolved "https://registry.yarnpkg.com/consola/-/consola-2.15.3.tgz#2e11f98d6a4be71ff72e0bdf07bd23e12cb61550" | ||||
|   integrity sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw== | ||||
| 
 | ||||
| console.table@0.10.0: | ||||
|   version "0.10.0" | ||||
|   resolved "https://registry.yarnpkg.com/console.table/-/console.table-0.10.0.tgz#0917025588875befd70cf2eff4bef2c6e2d75d04" | ||||
|   integrity sha1-CRcCVYiHW+/XDPLv9L7yxuLXXQQ= | ||||
|   dependencies: | ||||
|     easy-table "1.1.0" | ||||
| 
 | ||||
| content-disposition@0.5.4: | ||||
|   version "0.5.4" | ||||
|   resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" | ||||
| @ -3878,7 +3977,7 @@ data-urls@^2.0.0: | ||||
|     whatwg-mimetype "^2.3.0" | ||||
|     whatwg-url "^8.0.0" | ||||
| 
 | ||||
| date-fns@2.28.0: | ||||
| date-fns@2.28.0, date-fns@^2.16.1: | ||||
|   version "2.28.0" | ||||
|   resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.28.0.tgz#9570d656f5fc13143e50c975a3b6bbeb46cd08b2" | ||||
|   integrity sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw== | ||||
| @ -4175,6 +4274,13 @@ duplexer@^0.1.2: | ||||
|   resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" | ||||
|   integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== | ||||
| 
 | ||||
| easy-table@1.1.0: | ||||
|   version "1.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/easy-table/-/easy-table-1.1.0.tgz#86f9ab4c102f0371b7297b92a651d5824bc8cb73" | ||||
|   integrity sha1-hvmrTBAvA3G3KXuSplHVgkvIy3M= | ||||
|   optionalDependencies: | ||||
|     wcwidth ">=1.0.1" | ||||
| 
 | ||||
| ecc-jsbn@~0.1.1: | ||||
|   version "0.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" | ||||
| @ -4770,6 +4876,11 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: | ||||
|   resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" | ||||
|   integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= | ||||
| 
 | ||||
| fast-safe-stringify@2.1.1: | ||||
|   version "2.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" | ||||
|   integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== | ||||
| 
 | ||||
| fastq@^1.6.0: | ||||
|   version "1.13.0" | ||||
|   resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" | ||||
| @ -4904,7 +5015,7 @@ flatted@^3.1.0: | ||||
|   resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" | ||||
|   integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== | ||||
| 
 | ||||
| follow-redirects@^1.0.0: | ||||
| follow-redirects@^1.0.0, follow-redirects@^1.14.4: | ||||
|   version "1.14.9" | ||||
|   resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" | ||||
|   integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== | ||||
| @ -4966,6 +5077,15 @@ fresh@0.5.2: | ||||
|   resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" | ||||
|   integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= | ||||
| 
 | ||||
| fs-extra@10.0.0: | ||||
|   version "10.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" | ||||
|   integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== | ||||
|   dependencies: | ||||
|     graceful-fs "^4.2.0" | ||||
|     jsonfile "^6.0.1" | ||||
|     universalify "^2.0.0" | ||||
| 
 | ||||
| fs-extra@^10.0.0: | ||||
|   version "10.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.1.tgz#27de43b4320e833f6867cc044bfce29fdf0ef3b8" | ||||
| @ -5092,10 +5212,10 @@ glob-to-regexp@^0.4.1: | ||||
|   resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" | ||||
|   integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== | ||||
| 
 | ||||
| glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: | ||||
|   version "7.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" | ||||
|   integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== | ||||
| glob@7.1.6, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: | ||||
|   version "7.1.6" | ||||
|   resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" | ||||
|   integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== | ||||
|   dependencies: | ||||
|     fs.realpath "^1.0.0" | ||||
|     inflight "^1.0.4" | ||||
| @ -5263,11 +5383,16 @@ html-encoding-sniffer@^2.0.1: | ||||
|   dependencies: | ||||
|     whatwg-encoding "^1.0.5" | ||||
| 
 | ||||
| html-entities@^2.1.0, html-entities@^2.3.2: | ||||
| html-entities@^2.1.0: | ||||
|   version "2.3.3" | ||||
|   resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" | ||||
|   integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== | ||||
| 
 | ||||
| html-entities@^2.3.2: | ||||
|   version "2.3.2" | ||||
|   resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488" | ||||
|   integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ== | ||||
| 
 | ||||
| html-escaper@^2.0.0: | ||||
|   version "2.0.2" | ||||
|   resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" | ||||
| @ -5504,6 +5629,26 @@ ini@^1.3.5: | ||||
|   resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" | ||||
|   integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== | ||||
| 
 | ||||
| inquirer@8.2.0: | ||||
|   version "8.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.0.tgz#f44f008dd344bbfc4b30031f45d984e034a3ac3a" | ||||
|   integrity sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ== | ||||
|   dependencies: | ||||
|     ansi-escapes "^4.2.1" | ||||
|     chalk "^4.1.1" | ||||
|     cli-cursor "^3.1.0" | ||||
|     cli-width "^3.0.0" | ||||
|     external-editor "^3.0.3" | ||||
|     figures "^3.0.0" | ||||
|     lodash "^4.17.21" | ||||
|     mute-stream "0.0.8" | ||||
|     ora "^5.4.1" | ||||
|     run-async "^2.4.0" | ||||
|     rxjs "^7.2.0" | ||||
|     string-width "^4.1.0" | ||||
|     strip-ansi "^6.0.0" | ||||
|     through "^2.3.6" | ||||
| 
 | ||||
| inquirer@^8.2.0: | ||||
|   version "8.2.2" | ||||
|   resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.2.tgz#1310517a87a0814d25336c78a20b44c3d9b7629d" | ||||
| @ -5818,6 +5963,11 @@ istanbul-reports@^3.1.3: | ||||
|     html-escaper "^2.0.0" | ||||
|     istanbul-lib-report "^3.0.0" | ||||
| 
 | ||||
| iterare@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/iterare/-/iterare-1.2.1.tgz#139c400ff7363690e33abffa33cbba8920f00042" | ||||
|   integrity sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q== | ||||
| 
 | ||||
| jake@^10.6.1: | ||||
|   version "10.8.4" | ||||
|   resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.4.tgz#f6a8b7bf90c6306f768aa82bb7b98bf4ca15e84a" | ||||
| @ -6638,7 +6788,7 @@ lodash.uniq@^4.5.0: | ||||
|   resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" | ||||
|   integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= | ||||
| 
 | ||||
| lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: | ||||
| lodash@4.17.21, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: | ||||
|   version "4.17.21" | ||||
|   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" | ||||
|   integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== | ||||
| @ -6910,7 +7060,7 @@ no-case@^3.0.4: | ||||
|     lower-case "^2.0.2" | ||||
|     tslib "^2.0.3" | ||||
| 
 | ||||
| node-fetch@^2.6.7: | ||||
| node-fetch@^2.6.1, node-fetch@^2.6.7: | ||||
|   version "2.6.7" | ||||
|   resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" | ||||
|   integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== | ||||
| @ -6978,7 +7128,7 @@ object-assign@^4.1.1: | ||||
|   resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" | ||||
|   integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= | ||||
| 
 | ||||
| object-hash@^2.2.0: | ||||
| object-hash@2.2.0, object-hash@^2.2.0: | ||||
|   version "2.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" | ||||
|   integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== | ||||
| @ -7288,6 +7438,11 @@ path-to-regexp@0.1.7: | ||||
|   resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" | ||||
|   integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= | ||||
| 
 | ||||
| path-to-regexp@3.2.0: | ||||
|   version "3.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-3.2.0.tgz#fa7877ecbc495c601907562222453c43cc204a5f" | ||||
|   integrity sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA== | ||||
| 
 | ||||
| path-to-regexp@^1.7.0: | ||||
|   version "1.8.0" | ||||
|   resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" | ||||
| @ -8342,6 +8497,11 @@ redux@^4.1.2: | ||||
|   dependencies: | ||||
|     "@babel/runtime" "^7.9.2" | ||||
| 
 | ||||
| reflect-metadata@0.1.13: | ||||
|   version "0.1.13" | ||||
|   resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" | ||||
|   integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== | ||||
| 
 | ||||
| regenerate-unicode-properties@^10.0.1: | ||||
|   version "10.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" | ||||
| @ -8560,6 +8720,27 @@ run-parallel@^1.1.9: | ||||
|   dependencies: | ||||
|     queue-microtask "^1.2.2" | ||||
| 
 | ||||
| rxjs@7.5.2: | ||||
|   version "7.5.2" | ||||
|   resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.2.tgz#11e4a3a1dfad85dbf7fb6e33cbba17668497490b" | ||||
|   integrity sha512-PwDt186XaL3QN5qXj/H9DGyHhP3/RYYgZZwqBv9Tv8rsAaiwFH1IsJJlcgD37J7UW5a6O67qX0KWKS3/pu0m4w== | ||||
|   dependencies: | ||||
|     tslib "^2.1.0" | ||||
| 
 | ||||
| rxjs@^6.6.3: | ||||
|   version "6.6.7" | ||||
|   resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz" | ||||
|   integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== | ||||
|   dependencies: | ||||
|     tslib "^1.9.0" | ||||
| 
 | ||||
| rxjs@^7.2.0: | ||||
|   version "7.5.4" | ||||
|   resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.4.tgz#3d6bd407e6b7ce9a123e76b1e770dc5761aa368d" | ||||
|   integrity sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ== | ||||
|   dependencies: | ||||
|     tslib "^2.1.0" | ||||
| 
 | ||||
| rxjs@^7.5.1, rxjs@^7.5.5: | ||||
|   version "7.5.5" | ||||
|   resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.5.tgz#2ebad89af0f560f460ad5cc4213219e1f7dd4e9f" | ||||
| @ -8896,6 +9077,11 @@ sourcemap-codec@^1.4.8: | ||||
|   resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" | ||||
|   integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== | ||||
| 
 | ||||
| spawn-command@^0.0.2-1: | ||||
|   version "0.0.2-1" | ||||
|   resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" | ||||
|   integrity sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A= | ||||
| 
 | ||||
| spdy-transport@^3.0.0: | ||||
|   version "3.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" | ||||
| @ -9129,7 +9315,7 @@ supports-color@^7.0.0, supports-color@^7.1.0: | ||||
|   dependencies: | ||||
|     has-flag "^4.0.0" | ||||
| 
 | ||||
| supports-color@^8.0.0, supports-color@^8.1.1: | ||||
| supports-color@^8.0.0, supports-color@^8.1.0, supports-color@^8.1.1: | ||||
|   version "8.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" | ||||
|   integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== | ||||
| @ -9398,6 +9584,11 @@ tr46@~0.0.3: | ||||
|   resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" | ||||
|   integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= | ||||
| 
 | ||||
| tree-kill@^1.2.2: | ||||
|   version "1.2.2" | ||||
|   resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" | ||||
|   integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== | ||||
| 
 | ||||
| tryer@^1.0.1: | ||||
|   version "1.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" | ||||
| @ -9413,16 +9604,21 @@ tsconfig-paths@^3.14.1: | ||||
|     minimist "^1.2.6" | ||||
|     strip-bom "^3.0.0" | ||||
| 
 | ||||
| tslib@^1.8.1: | ||||
|   version "1.14.1" | ||||
|   resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" | ||||
|   integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== | ||||
| tslib@2.0.3: | ||||
|   version "2.0.3" | ||||
|   resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" | ||||
|   integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== | ||||
| 
 | ||||
| tslib@^2.0.3, tslib@^2.1.0: | ||||
| tslib@2.3.1, tslib@^2.0.3, tslib@^2.1.0: | ||||
|   version "2.3.1" | ||||
|   resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" | ||||
|   integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== | ||||
| 
 | ||||
| tslib@^1.8.1, tslib@^1.9.0: | ||||
|   version "1.14.1" | ||||
|   resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" | ||||
|   integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== | ||||
| 
 | ||||
| tsutils@^3.21.0: | ||||
|   version "3.21.0" | ||||
|   resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" | ||||
| @ -9603,9 +9799,9 @@ utils-merge@1.0.1: | ||||
|   resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" | ||||
|   integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= | ||||
| 
 | ||||
| uuid@^8.3.2: | ||||
| uuid@8.3.2, uuid@^8.3.2: | ||||
|   version "8.3.2" | ||||
|   resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" | ||||
|   resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" | ||||
|   integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== | ||||
| 
 | ||||
| v8-compile-cache@^2.0.3: | ||||
| @ -9677,7 +9873,7 @@ wbuf@^1.1.0, wbuf@^1.7.3: | ||||
|   dependencies: | ||||
|     minimalistic-assert "^1.0.0" | ||||
| 
 | ||||
| wcwidth@^1.0.1: | ||||
| wcwidth@>=1.0.1, wcwidth@^1.0.1: | ||||
|   version "1.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" | ||||
|   integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user