mirror of
https://github.com/langgenius/dify.git
synced 2026-07-22 19:48:36 +08:00
173 lines
5.6 KiB
TypeScript
173 lines
5.6 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,
|
|
})
|
|
})
|