From bde2b294dbba4c880824af0dd7c43d5ef94362f6 Mon Sep 17 00:00:00 2001 From: Basit Ayantunde Date: Tue, 21 Nov 2023 14:36:09 +0000 Subject: [PATCH] added conda support update removed logging --- src/api/clearlyDefined.js | 12 +++ src/components/DefinitionEntry.js | 4 +- src/components/FilterBar.js | 2 + src/components/HarvestQueueList.js | 19 ++++ .../Pages/PageHarvest/PageHarvest.js | 4 + .../Navigation/Pages/PageStats/PageStats.js | 3 + .../Navigation/Ui/ComponentButtons.js | 4 +- .../Navigation/Ui/ComponentDetailsButtons.js | 2 +- .../Providers/Selectors/CondaSelector.js | 65 ++++++++++++ .../VersionPickers/CondaVersionPicker.js | 75 ++++++++++++++ src/components/index.js | 94 +++++++++--------- src/images/anaconda-main.svg | 5 + src/images/anaconda-r.png | Bin 0 -> 15256 bytes src/images/conda-forge.png | Bin 0 -> 9197 bytes src/images/conda.svg | 1 + src/utils/contribution.js | 11 +- src/utils/utils.js | 8 ++ 17 files changed, 259 insertions(+), 50 deletions(-) create mode 100644 src/components/Providers/Selectors/CondaSelector.js create mode 100644 src/components/Providers/VersionPickers/CondaVersionPicker.js create mode 100644 src/images/anaconda-main.svg create mode 100644 src/images/anaconda-r.png create mode 100644 src/images/conda-forge.png create mode 100644 src/images/conda.svg diff --git a/src/api/clearlyDefined.js b/src/api/clearlyDefined.js index 8da2f9e1..490d4941 100644 --- a/src/api/clearlyDefined.js +++ b/src/api/clearlyDefined.js @@ -17,6 +17,7 @@ export const BROWSE = 'browse' export const ORIGINS_GITHUB = 'origins/github' export const ORIGINS_NPM = 'origins/npm' export const ORIGINS_NUGET = 'origins/nuget' +export const ORIGINS_CONDA = 'origins/conda' export const ORIGINS_CRATE = 'origins/crate' export const ORIGINS_MAVEN = 'origins/maven' export const ORIGINS_PYPI = 'origins/pypi' @@ -25,9 +26,12 @@ export const ORIGINS_DEBIAN = 'origins/deb' export const ORIGINS_COMPOSER = 'origins/composer' export const ORIGINS_POD = 'origins/pod' export const ORIGINS = { + "anaconda-main": { conda: ORIGINS_CONDA, condasource: ORIGINS_CONDA }, + "anaconda-r": { conda: ORIGINS_CONDA, condasource: ORIGINS_CONDA }, github: { git: ORIGINS_GITHUB }, npmjs: { npm: ORIGINS_NPM }, nuget: { nuget: ORIGINS_NUGET }, + "conda-forge": { conda: ORIGINS_CONDA, condasource: ORIGINS_CONDA }, cratesio: { crate: ORIGINS_CRATE }, mavencentral: { maven: ORIGINS_MAVEN, sourcearchive: ORIGINS_MAVEN }, pypi: { pypi: ORIGINS_PYPI }, @@ -188,6 +192,14 @@ export function getRubyGemsRevisions(token, path) { return get(url(`${ORIGINS_RUBYGEMS}/${path}/revisions`), token) } +export function getCondaSearch(token, path) { + return get(url(`${ORIGINS_CONDA}/${path}`), token) +} + +export function getCondaRevisions(token, path) { + return get(url(`${ORIGINS_CONDA}/${path}/revisions`), token) +} + export function getCrateSearch(token, path) { return get(url(`${ORIGINS_CRATE}/${path}`), token) } diff --git a/src/components/DefinitionEntry.js b/src/components/DefinitionEntry.js index c4bd4646..c6b96731 100644 --- a/src/components/DefinitionEntry.js +++ b/src/components/DefinitionEntry.js @@ -11,6 +11,7 @@ import git from '../images/Git-Logo-2Color.png' import npm from '../images/n-large.png' import pypi from '../images/pypi.png' import gem from '../images/gem.png' +import conda from '../images/conda.svg' import cargo from '../images/cargo.png' import nuget from '../images/nuget.svg' import debian from '../images/debian.png' @@ -49,7 +50,7 @@ class DefinitionEntry extends React.Component { static defaultProps = {} isSourceComponent(component) { - return ['github', 'sourcearchive', 'debsrc'].includes(component.provider) + return ['github', 'sourcearchive', 'debsrc', 'condasource'].includes(component.provider) } fieldChange(field, equality = isEqual, transform = a => a) { @@ -453,6 +454,7 @@ class DefinitionEntry extends React.Component { getImage(definition) { if (definition.coordinates.type === 'git') return git if (definition.coordinates.type === 'npm') return npm + if (definition.coordinates.type === 'conda') return conda if (definition.coordinates.type === 'crate') return cargo if (definition.coordinates.type === 'pypi') return pypi if (definition.coordinates.type === 'gem') return gem diff --git a/src/components/FilterBar.js b/src/components/FilterBar.js index f3c28585..8fd535f3 100644 --- a/src/components/FilterBar.js +++ b/src/components/FilterBar.js @@ -10,6 +10,7 @@ import maven from '../images/maven.png' import nuget from '../images/nuget.png' import pod from '../images/pod.png' import git from '../images/Git-Logo-2Color.png' +import conda from '../images/conda.svg' import crate from '../images/cargo.png' import gem from '../images/gem.png' import pypi from '../images/pypi.png' @@ -23,6 +24,7 @@ const types = { maven: maven, nuget: nuget, git: git, + conda: conda, crate: crate, pod: pod, deb: debian, diff --git a/src/components/HarvestQueueList.js b/src/components/HarvestQueueList.js index a2f62ae4..47af160c 100644 --- a/src/components/HarvestQueueList.js +++ b/src/components/HarvestQueueList.js @@ -11,6 +11,7 @@ import { NpmVersionPicker, MavenVersionPicker, PyPiVersionPicker, + CondaVersionPicker, CrateVersionPicker, DebianVersionPicker, NuGetVersionPicker, @@ -25,6 +26,9 @@ import npm from '../images/n-large.png' import pypi from '../images/pypi.png' import debian from '../images/debian.png' import gem from '../images/gem.png' +import anaconda_main from '../images/anaconda-main.svg' +import anaconda_r from '../images/anaconda-r.png' +import conda_forge from '../images/conda-forge.png' import cargo from '../images/cargo.png' import maven from '../images/maven.png' import nuget from '../images/nuget.png' @@ -84,6 +88,15 @@ class HarvestQueueList extends React.Component { onChange={this.commitChanged.bind(this, request)} /> )} + {request.provider === 'anaconda-main' && ( + + )} + {request.provider === 'anaconda-r' && ( + + )} + {request.provider === 'cratesio' && ( + + )} {request.provider === 'npmjs' && ( )} @@ -96,6 +109,9 @@ class HarvestQueueList extends React.Component { {request.provider === 'rubygems' && ( )} + {request.provider === 'conda-forge' && ( + + )} {request.provider === 'cratesio' && ( )} @@ -150,6 +166,9 @@ class HarvestQueueList extends React.Component { if (request.provider === 'npmjs') return npm if (request.provider === 'pypi') return pypi if (request.provider === 'rubygems') return gem + if (request.provider === 'anaconda-main') return anaconda_main + if (request.provider === 'anaconda-r') return anaconda_r + if (request.provider === 'conda-forge') return conda_forge if (request.provider === 'cratesio') return cargo if (request.provider === 'mavencentral') return maven if (request.provider === 'nuget') return nuget diff --git a/src/components/Navigation/Pages/PageHarvest/PageHarvest.js b/src/components/Navigation/Pages/PageHarvest/PageHarvest.js index 0cf346e1..c7c5edfd 100644 --- a/src/components/Navigation/Pages/PageHarvest/PageHarvest.js +++ b/src/components/Navigation/Pages/PageHarvest/PageHarvest.js @@ -12,6 +12,7 @@ import { NpmSelector, MavenSelector, NuGetSelector, + CondaSelector, CrateSelector, DebianSelector, ComposerSelector, @@ -114,11 +115,14 @@ class PageHarvest extends Component { {this.renderProviderButtons()} + {activeProvider.value === 'anaconda-main' && } + {activeProvider.value === 'anaconda-r' && } {activeProvider.value === 'github' && } {activeProvider.value === 'mavencentral' && } {activeProvider.value === 'npmjs' && } {activeProvider.value === 'nuget' && } {activeProvider.value === 'cratesio' && } + {activeProvider.value === 'conda-forge' && } {activeProvider.value === 'packagist' && } {activeProvider.value === 'pypi' && } {activeProvider.value === 'rubygems' && } diff --git a/src/components/Navigation/Pages/PageStats/PageStats.js b/src/components/Navigation/Pages/PageStats/PageStats.js index 599db4f4..8d6f1e91 100644 --- a/src/components/Navigation/Pages/PageStats/PageStats.js +++ b/src/components/Navigation/Pages/PageStats/PageStats.js @@ -13,6 +13,7 @@ import maven from '../../../../images/maven.png' import nuget from '../../../../images/nuget.png' import pod from '../../../../images/pod.png' import git from '../../../../images/Git-Logo-2Color.png' +import conda from '../../../../images/conda.svg' import crate from '../../../../images/cargo.png' import composer from '../../../../images/packagist.png' import gem from '../../../../images/gem.png' @@ -34,6 +35,8 @@ const types = { maven: maven, nuget: nuget, git: git, + conda: conda, + condasource: conda, crate: crate, deb: debian, debsrc: debian, diff --git a/src/components/Navigation/Ui/ComponentButtons.js b/src/components/Navigation/Ui/ComponentButtons.js index acf9a479..3c16fad9 100644 --- a/src/components/Navigation/Ui/ComponentButtons.js +++ b/src/components/Navigation/Ui/ComponentButtons.js @@ -32,7 +32,7 @@ class ComponentButtons extends Component { } isSourceComponent(component) { - return ['github', 'sourcearchive', 'debsrc'].includes(component.provider) + return ['github', 'sourcearchive', 'debsrc', 'condasource'].includes(component.provider) } _isProviderSupported(component) { @@ -152,7 +152,7 @@ class ComponentButtons extends Component { )} {!isDefinitionEmpty && onInspect && ( - diff --git a/src/components/Navigation/Ui/ComponentDetailsButtons.js b/src/components/Navigation/Ui/ComponentDetailsButtons.js index d1040625..f7378c6c 100644 --- a/src/components/Navigation/Ui/ComponentDetailsButtons.js +++ b/src/components/Navigation/Ui/ComponentDetailsButtons.js @@ -14,7 +14,7 @@ class ComponentDetailsButtons extends Component { } isSourceComponent(component) { - return ['github', 'sourcearchive', 'debsrc'].includes(component.provider) + return ['github', 'sourcearchive', 'debsrc', 'condasource'].includes(component.provider) } openSourceForComponent = definition => { diff --git a/src/components/Providers/Selectors/CondaSelector.js b/src/components/Providers/Selectors/CondaSelector.js new file mode 100644 index 00000000..1ff25750 --- /dev/null +++ b/src/components/Providers/Selectors/CondaSelector.js @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation and others. Licensed under the MIT license. +// SPDX-License-Identifier: MIT + +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { getCondaSearch } from '../../../api/clearlyDefined' +import { AsyncTypeahead } from 'react-bootstrap-typeahead' +import searchSvg from '../../../images/icons/searchSvg.svg' + +export default class CondaSelector extends Component { + static propTypes = { + onChange: PropTypes.func + } + + constructor(props) { + super(props) + this.state = { isLoading: false, options: [], focus: false } + this.getOptions = this.getOptions.bind(this) + this.onChange = this.onChange.bind(this) + } + + onChange(values) { + const { onChange } = this.props + const value = values.length === 0 ? null : values[0] + value && onChange && onChange({ type: 'conda', provider: this.props.provider, name: value.id }, 'package') + } + + async getOptions(value) { + try { + this.setState({ ...this.state, isLoading: true }) + const options = await getCondaSearch(this.props.token, `${value}/${this.props.provider}`) + this.setState({ ...this.state, options, isLoading: false }) + } catch (error) { + this.setState({ ...this.state, options: [], isLoading: false }) + } + } + + render() { + const { options, isLoading, focus } = this.state + return ( +
+
+ search +
+ this.setState({ ...this.state, focus: true })} + onBlur={() => this.setState({ ...this.state, focus: false })} + clearButton + highlightOnlyResult + emptyLabel="" + selectHintOnEnter + isLoading={isLoading} + onSearch={this.getOptions} + /> +
+ ) + } +} diff --git a/src/components/Providers/VersionPickers/CondaVersionPicker.js b/src/components/Providers/VersionPickers/CondaVersionPicker.js new file mode 100644 index 00000000..e265d81d --- /dev/null +++ b/src/components/Providers/VersionPickers/CondaVersionPicker.js @@ -0,0 +1,75 @@ +// Copyright (c) Microsoft Corporation and others. Licensed under the MIT license. +// SPDX-License-Identifier: MIT + +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { getCondaRevisions } from '../../../api/clearlyDefined' +import Autocomplete from '../../Navigation/Ui/Autocomplete' + +export default class CondaVersionPicker extends Component { + static propTypes = { + onChange: PropTypes.func, + request: PropTypes.object.isRequired, + defaultInputValue: PropTypes.string + } + + constructor(props) { + super(props) + this.state = { customValues: [], options: [] } + this.onChange = this.onChange.bind(this) + this.filter = this.filter.bind(this) + } + + componentDidMount() { + this.getOptions('') + } + + async getOptions(value) { + try { + const { name, provider } = this.props.request + const options = await getCondaRevisions(this.props.token, `${name}/${provider}`) + this.setState({ ...this.state, options }) + } catch (error) { + this.setState({ ...this.state, options: [] }) + } + } + + onChange(values) { + const { onChange } = this.props + if (!onChange) return + let value = values.length === 0 ? null : values[0] + if (!value) return onChange(value) + if (value.customOption) { + value = value.label + this.setState({ ...this.state, customValues: [...this.state.customValues, value] }) + } + onChange(value) + } + + filter(option, props) { + if (this.props.request.revision) return true + return option.toLowerCase().indexOf(props.text.toLowerCase()) !== -1 + } + + render() { + const { defaultInputValue } = this.props + const { customValues, options } = this.state + const list = customValues.concat(options) + return ( + + ) + } +} diff --git a/src/components/index.js b/src/components/index.js index d4bd0136..42f3994e 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -2,92 +2,96 @@ // SPDX-License-Identifier: MIT export { default as App } -from './App' + from './App' export { default as Clearly } -from './Clearly' + from './Clearly' export { default as ComponentList } -from './ComponentList' + from './ComponentList' export { default as ContributePrompt } -from './ContributePrompt' + from './ContributePrompt' export { default as CopyUrlButton } -from './CopyUrlButton' + from './CopyUrlButton' +export { default as CondaSelector } + from './Providers/Selectors/CondaSelector' +export { default as CondaVersionPicker } + from './Providers/VersionPickers/CondaVersionPicker' export { default as CrateSelector } -from './Providers/Selectors/CrateSelector' + from './Providers/Selectors/CrateSelector' export { default as CrateVersionPicker } -from './Providers/VersionPickers/CrateVersionPicker' + from './Providers/VersionPickers/CrateVersionPicker' export { default as DebianSelector } -from './Providers/Selectors/DebianSelector' + from './Providers/Selectors/DebianSelector' export { default as DebianVersionPicker } -from './Providers/VersionPickers/DebianVersionPicker' + from './Providers/VersionPickers/DebianVersionPicker' export { default as ComposerSelector } -from './Providers/Selectors/ComposerSelector' + from './Providers/Selectors/ComposerSelector' export { default as ComposerVersionPicker } -from './Providers/VersionPickers/ComposerVersionPicker' + from './Providers/VersionPickers/ComposerVersionPicker' export { default as DefinitionEntry } -from './DefinitionEntry' + from './DefinitionEntry' export { default as FieldGroup } -from './FieldGroup' + from './FieldGroup' export { default as FileCountRenderer } -from './FileCountRenderer' + from './FileCountRenderer' export { default as FilterBar } -from './FilterBar' + from './FilterBar' export { default as Footer } -from './Footer' + from './Footer' export { default as GitHubCommitPicker } -from './Providers/VersionPickers/GitHubCommitPicker' + from './Providers/VersionPickers/GitHubCommitPicker' export { default as GitHubSelector } -from './Providers/Selectors/GitHubSelector' + from './Providers/Selectors/GitHubSelector' export { default as HarvestQueueList } -from './HarvestQueueList' + from './HarvestQueueList' export { default as Header } -from './Header' + from './Header' export { default as InfiniteList } -from './InfiniteList' + from './InfiniteList' export { default as InlineEditor } -from './InlineEditor' + from './InlineEditor' export { default as ModalEditor } -from './ModalEditor' + from './ModalEditor' export { default as SourcePicker } -from './SourcePicker' + from './SourcePicker' export { default as MavenSelector } -from './Providers/Selectors/MavenSelector' + from './Providers/Selectors/MavenSelector' export { default as MavenVersionPicker } -from './Providers/VersionPickers/MavenVersionPicker' + from './Providers/VersionPickers/MavenVersionPicker' export { default as NotificationList } -from './NotificationList' + from './NotificationList' export { default as NpmSelector } -from './Providers/Selectors/NpmSelector' + from './Providers/Selectors/NpmSelector' export { default as NpmVersionPicker } -from './Providers/VersionPickers/NpmVersionPicker' + from './Providers/VersionPickers/NpmVersionPicker' export { default as NuGetSelector } -from './Providers/Selectors/NuGetSelector' + from './Providers/Selectors/NuGetSelector' export { default as NuGetVersionPicker } -from './Providers/VersionPickers/NuGetVersionPicker' + from './Providers/VersionPickers/NuGetVersionPicker' export { default as PyPiSelector } -from './Providers/Selectors/PyPiSelector' + from './Providers/Selectors/PyPiSelector' export { default as PyPiVersionPicker } -from './Providers/VersionPickers/PyPiVersionPicker' + from './Providers/VersionPickers/PyPiVersionPicker' export { default as RubyGemsSelector } -from './Providers/Selectors/RubyGemsSelector' + from './Providers/Selectors/RubyGemsSelector' export { default as RubyGemsVersionPicker } -from './Providers/VersionPickers/RubyGemsVersionPicker' + from './Providers/VersionPickers/RubyGemsVersionPicker' export { default as CocoaPodsSelector } -from './Providers/Selectors/CocoaPodsSelector' + from './Providers/Selectors/CocoaPodsSelector' export { default as CocoaPodsVersionPicker } -from './Providers/VersionPickers/CocoaPodsVersionPicker' + from './Providers/VersionPickers/CocoaPodsVersionPicker' export { default as PageAbout } -from './PageAbout' + from './PageAbout' export { default as RehydrationProvider } -from './RehydrationProvider' + from './RehydrationProvider' export { default as RowEntityList } -from './RowEntityList' + from './RowEntityList' export { default as Section } -from './Section' + from './Section' export { default as SocialIcons } -from './SocialIcons' + from './SocialIcons' export { default as SpdxPicker } -from './SpdxPicker' + from './SpdxPicker' export { default as TwoLineEntry } -from './TwoLineEntry' + from './TwoLineEntry' export { default as QuickEditModel } -from './QuickEditModel' + from './QuickEditModel' diff --git a/src/images/anaconda-main.svg b/src/images/anaconda-main.svg new file mode 100644 index 00000000..aea6b8cc --- /dev/null +++ b/src/images/anaconda-main.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/images/anaconda-r.png b/src/images/anaconda-r.png new file mode 100644 index 0000000000000000000000000000000000000000..2f720fd5052cd28960a52e9c1eeb991e1ebdaa0b GIT binary patch literal 15256 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

y_b}$@AZnyRJ#U_uOvmQMl$8OtJ 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 literal 0 HcmV?d00001 diff --git a/src/images/conda-forge.png b/src/images/conda-forge.png new file mode 100644 index 0000000000000000000000000000000000000000..256194881d5d2afd5814e9f9acbe3ceef95ee8be GIT binary patch literal 9197 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 literal 0 HcmV?d00001 diff --git a/src/images/conda.svg b/src/images/conda.svg new file mode 100644 index 00000000..3ad2de74 --- /dev/null +++ b/src/images/conda.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/utils/contribution.js b/src/utils/contribution.js index e2c79631..821eeaba 100644 --- a/src/utils/contribution.js +++ b/src/utils/contribution.js @@ -15,6 +15,9 @@ import github from '../images/GitHub-Mark-120px-plus.png' import npm from '../images/n-large.png' import pypi from '../images/pypi.png' import gem from '../images/gem.png' +import anaconda_r from '../images/anaconda-r.png' +import anaconda_main from '../images/anaconda-main.svg' +import conda_forge from '../images/conda-forge.png' import cargo from '../images/cargo.png' import nuget from '../images/nuget.svg' import debian from '../images/debian.png' @@ -198,7 +201,7 @@ export default class Contribution { static getPercentage = (count, total) => Math.round(((count || 0) / total) * 100) - static isSourceComponent = component => ['github', 'sourcearchive', 'debsrc'].includes(component.provider) + static isSourceComponent = component => ['github', 'sourcearchive', 'debsrc', 'condasource'].includes(component.provider) /** * Get image of definition based on the provider @@ -208,6 +211,10 @@ export default class Contribution { */ static getImage(item) { switch (item.coordinates.provider) { + case 'anaconda-main': + return anaconda_main + case 'anaconda-r': + return anaconda_r case 'github': return github case 'npmjs': @@ -216,6 +223,8 @@ export default class Contribution { return pypi case 'rubygems': return gem + case 'conda-forge': + return conda_forge case 'cratesio': return cargo case 'packagist': diff --git a/src/utils/utils.js b/src/utils/utils.js index 30c0b923..fabc02f3 100644 --- a/src/utils/utils.js +++ b/src/utils/utils.js @@ -1,11 +1,14 @@ // Copyright (c) Microsoft Corporation and others. Licensed under the MIT license. // SPDX-License-Identifier: MIT +import anacondaMainImage from '../images/anaconda-main.svg' +import anacondaRImage from '../images/anaconda-r.png' import deepDiff from 'deep-diff' import npmImage from '../images/n-large.png' import mavenImage from '../images/maven.png' import nugetImage from '../images/nuget.svg' import podImage from '../images/pod.png' import gitImage from '../images/Git-Logo-2Color.png' +import condaForgeImage from '../images/conda-forge.png' import crateImage from '../images/cargo.png' import gemImage from '../images/gem.png' import pypiImage from '../images/pypi.png' @@ -108,6 +111,8 @@ const curateFilters = [ const types = [ { value: 'composer', label: 'Composer', provider: 'packagist' }, { value: 'pod', label: 'Pod', provider: 'cocoapods' }, + { value: 'conda', label: 'Conda', provider: 'conda-forge' }, + { value: 'condasource', label: 'Conda', provider: 'conda-forge' }, { value: 'crate', label: 'Crate', provider: 'cratesio' }, { value: 'git', label: 'Git', provider: 'github' }, { value: 'maven', label: 'Maven', provider: 'mavencentral' }, @@ -121,6 +126,8 @@ const types = [ ] const providers = [ + { value: 'anaconda-main', label: 'Anaconda /main', image: anacondaMainImage, type: 'conda' }, + { value: 'anaconda-r', label: 'Anaconda /r', image: anacondaRImage, type: 'conda' }, { value: 'npmjs', label: 'NpmJS', image: npmImage, type: 'npm' }, { value: 'github', label: 'GitHub', image: gitImage, type: 'git' }, { value: 'mavencentral', label: 'MavenCentral', image: mavenImage, type: 'maven' }, @@ -128,6 +135,7 @@ const providers = [ { value: 'pypi', label: 'PyPI', image: pypiImage, type: 'pypi' }, { value: 'rubygems', label: 'RubyGems', image: gemImage, type: 'gem' }, { value: 'cocoapods', label: 'CocoaPods', image: podImage, type: 'pod' }, + { value: 'conda-forge', label: 'Conda-Forge', image: condaForgeImage, type: 'conda' }, { value: 'cratesio', label: 'Crates.io', image: crateImage, type: 'crate' }, { value: 'debian', label: 'Debian', image: debianImage, type: 'deb' }, { value: 'packagist', label: 'Packagist', image: composerImage, type: 'composer' }