mirror of
https://github.com/langgenius/dify.git
synced 2026-07-21 10:38:32 +08:00
152 lines
5.4 KiB
TypeScript
152 lines
5.4 KiB
TypeScript
'use client'
|
|
|
|
import type { EnvVarBindingSlot, EnvVarValueSelection } from '@/features/deployments/shared/components/env-var-bindings'
|
|
import { atom } from 'jotai'
|
|
import { envVarBindingSlotFromContract, envVarBindingValueType } from '@/features/deployments/shared/components/env-var-bindings-utils'
|
|
import {
|
|
hasMissingRequiredRuntimeCredentialBinding,
|
|
runtimeCredentialSlotKey,
|
|
selectedRuntimeCredentialSelections,
|
|
} from '@/features/deployments/shared/components/runtime-credential-bindings-utils'
|
|
import { dslEnvVarSlots } from '@/features/deployments/shared/domain/dsl'
|
|
import { environmentMatchesIdentifier } from './environment'
|
|
import { effectiveMethodAtom, envVarValuesAtom, manualBindingSelectionsAtom, selectedEnvironmentIdAtom } from './primitives'
|
|
import { deployableEnvironmentsDataAtom, deploymentOptionsDataAtom, deploymentOptionsReadyAtom } from './queries'
|
|
import { submittedReleaseReadyAtom } from './release'
|
|
import { dslContentAtom, sourceReady } from './source'
|
|
import { envVarSelectionReady } from './utils'
|
|
|
|
export const deployableEnvironmentsAtom = atom((get) => {
|
|
const deployableEnvironments = get(deployableEnvironmentsDataAtom)
|
|
|
|
return sourceReady(get)
|
|
? deployableEnvironments?.environments ?? []
|
|
: []
|
|
})
|
|
|
|
const deployableEnvironmentsReadyAtom = atom((get) => {
|
|
return sourceReady(get) && Boolean(get(deployableEnvironmentsDataAtom))
|
|
})
|
|
|
|
export const effectiveSelectedEnvironmentIdAtom = atom((get) => {
|
|
return get(selectedEnvironmentIdAtom) || get(deployableEnvironmentsAtom)[0]?.id
|
|
})
|
|
|
|
export const deploymentTargetBindingSlotsAtom = atom((get) => {
|
|
const deploymentOptions = get(deploymentOptionsDataAtom)
|
|
|
|
return sourceReady(get)
|
|
? deploymentOptions?.options?.credentialSlots?.filter(slot => runtimeCredentialSlotKey(slot)) ?? []
|
|
: []
|
|
})
|
|
|
|
export const deploymentTargetBindingSelectionsAtom = atom((get) => {
|
|
return selectedRuntimeCredentialSelections(
|
|
get(deploymentTargetBindingSlotsAtom),
|
|
get(manualBindingSelectionsAtom),
|
|
)
|
|
})
|
|
|
|
export const requiredBindingsReadyAtom = atom((get) => {
|
|
const bindingSelections = get(deploymentTargetBindingSelectionsAtom)
|
|
|
|
return get(deploymentTargetBindingSlotsAtom).every(slot =>
|
|
!hasMissingRequiredRuntimeCredentialBinding(slot, bindingSelections[runtimeCredentialSlotKey(slot)]),
|
|
)
|
|
})
|
|
|
|
export const deploymentTargetEnvVarSlotsAtom = atom((get) => {
|
|
const method = get(effectiveMethodAtom)
|
|
const deploymentOptions = get(deploymentOptionsDataAtom)
|
|
const slots = sourceReady(get) ? deploymentOptions?.options?.envVarSlots : undefined
|
|
const dslContent = get(dslContentAtom)
|
|
|
|
// Deployment options own the canonical slot list; DSL metadata only enriches import-DSL defaults.
|
|
const deploymentOptionEnvVarSlots = slots?.flatMap((slot): EnvVarBindingSlot[] => {
|
|
const bindingSlot = envVarBindingSlotFromContract(slot)
|
|
return bindingSlot ? [bindingSlot] : []
|
|
}) ?? []
|
|
const dslEnvVarMetadataSlots = method === 'importDsl' && dslContent
|
|
? dslEnvVarSlots(dslContent).flatMap((slot) => {
|
|
const key = slot.key.trim()
|
|
if (!key)
|
|
return []
|
|
|
|
return [{
|
|
key,
|
|
...(slot.description ? { description: slot.description } : {}),
|
|
...(slot.defaultValue !== undefined ? { defaultValue: slot.defaultValue, hasDefaultValue: true } : {}),
|
|
...(slot.valueType ? { valueType: envVarBindingValueType(slot.valueType) } : {}),
|
|
}]
|
|
})
|
|
: []
|
|
|
|
if (dslEnvVarMetadataSlots.length === 0)
|
|
return deploymentOptionEnvVarSlots
|
|
|
|
const metadataByKey = new Map(
|
|
dslEnvVarMetadataSlots.map(slot => [slot.key, slot] as const),
|
|
)
|
|
|
|
return deploymentOptionEnvVarSlots.map((slot) => {
|
|
const metadata = metadataByKey.get(slot.key)
|
|
if (!metadata)
|
|
return slot
|
|
|
|
const nextSlot = { ...slot }
|
|
|
|
if (!nextSlot.description && metadata.description)
|
|
nextSlot.description = metadata.description
|
|
if (!nextSlot.hasDefaultValue && metadata.defaultValue !== undefined) {
|
|
nextSlot.defaultValue = metadata.defaultValue
|
|
nextSlot.hasDefaultValue = true
|
|
}
|
|
if (nextSlot.valueType === 'string' && metadata.valueType)
|
|
nextSlot.valueType = metadata.valueType
|
|
|
|
return nextSlot
|
|
})
|
|
})
|
|
|
|
export const requiredEnvVarsReadyAtom = atom((get) => {
|
|
const envVarValues = get(envVarValuesAtom)
|
|
|
|
return get(deploymentTargetEnvVarSlotsAtom).every(slot =>
|
|
envVarSelectionReady(slot, envVarValues[slot.key]),
|
|
)
|
|
})
|
|
|
|
export const canDeployAtom = atom((get) => {
|
|
const effectiveSelectedEnvironmentId = get(effectiveSelectedEnvironmentIdAtom)
|
|
const selectedEnvironment = effectiveSelectedEnvironmentId
|
|
? get(deployableEnvironmentsAtom).find(env => environmentMatchesIdentifier(env, effectiveSelectedEnvironmentId))
|
|
: undefined
|
|
|
|
return Boolean(
|
|
selectedEnvironment?.id
|
|
&& get(deployableEnvironmentsReadyAtom)
|
|
&& get(deploymentOptionsReadyAtom)
|
|
&& get(requiredBindingsReadyAtom)
|
|
&& get(requiredEnvVarsReadyAtom)
|
|
&& get(submittedReleaseReadyAtom),
|
|
)
|
|
})
|
|
|
|
export const canSkipDeploymentAtom = atom((get) => {
|
|
return get(submittedReleaseReadyAtom) && get(deploymentOptionsReadyAtom)
|
|
})
|
|
|
|
export const selectBindingAtom = atom(null, (get, set, slot: string, value: string) => {
|
|
set(manualBindingSelectionsAtom, {
|
|
...get(manualBindingSelectionsAtom),
|
|
[slot]: value,
|
|
})
|
|
})
|
|
|
|
export const setEnvVarAtom = atom(null, (get, set, key: string, value: EnvVarValueSelection) => {
|
|
set(envVarValuesAtom, {
|
|
...get(envVarValuesAtom),
|
|
[key]: value,
|
|
})
|
|
})
|