chore: resolve global env in team env and tooltip UI update (#5187)
This commit is contained in:
parent
594f078b4e
commit
427a1811a5
11 changed files with 303 additions and 135 deletions
|
|
@ -158,7 +158,6 @@ a {
|
|||
@apply shadow-none #{!important};
|
||||
@apply fixed;
|
||||
@apply inline-flex;
|
||||
@apply -mt-7;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -169,7 +168,7 @@ a {
|
|||
@apply shadow;
|
||||
|
||||
.tippy-content {
|
||||
@apply flex;
|
||||
@apply flex flex-col;
|
||||
@apply text-tiny text-primary;
|
||||
@apply font-semibold;
|
||||
@apply px-2 py-1;
|
||||
|
|
|
|||
|
|
@ -407,12 +407,14 @@
|
|||
"added": "Environment addition",
|
||||
"create_new": "Create new environment",
|
||||
"created": "Environment created",
|
||||
"current_value": "Current value",
|
||||
"deleted": "Environment deletion",
|
||||
"duplicated": "Environment duplicated",
|
||||
"edit": "Edit Environment",
|
||||
"empty_variables": "No variables",
|
||||
"global": "Global",
|
||||
"global_variables": "Global variables",
|
||||
"initial_value": "Initial value",
|
||||
"import_or_create": "Import or create a environment",
|
||||
"invalid_name": "Please provide a name for the environment",
|
||||
"list": "Environment variables",
|
||||
|
|
|
|||
|
|
@ -239,9 +239,14 @@
|
|||
{{ t("environment.name") }}
|
||||
</span>
|
||||
<span
|
||||
class="min-w-[9rem] w-full truncate text-tiny font-semibold"
|
||||
class="min-w-[4rem] w-full truncate text-tiny font-semibold"
|
||||
>
|
||||
{{ t("environment.value") }}
|
||||
{{ t("environment.initial_value") }}
|
||||
</span>
|
||||
<span
|
||||
class="min-w-[4rem] w-full truncate text-tiny font-semibold"
|
||||
>
|
||||
{{ t("environment.current_value") }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
|
|
@ -252,7 +257,13 @@
|
|||
<span class="min-w-[9rem] w-1/4 truncate text-secondaryLight">
|
||||
{{ variable.key }}
|
||||
</span>
|
||||
<span class="min-w-[9rem] w-full truncate text-secondaryLight">
|
||||
<span class="min-w-[4rem] w-full truncate text-secondaryLight">
|
||||
<template v-if="variable.secret"> ******** </template>
|
||||
<template v-else>
|
||||
{{ variable.initialValue }}
|
||||
</template>
|
||||
</span>
|
||||
<span class="min-w-[4rem] w-full truncate text-secondaryLight">
|
||||
<template v-if="variable.secret"> ******** </template>
|
||||
<template v-else>
|
||||
{{ variable.currentValue }}
|
||||
|
|
@ -297,9 +308,14 @@
|
|||
{{ t("environment.name") }}
|
||||
</span>
|
||||
<span
|
||||
class="min-w-[9rem] w-full truncate text-tiny font-semibold"
|
||||
class="min-w-[4rem] w-full truncate text-tiny font-semibold"
|
||||
>
|
||||
{{ t("environment.value") }}
|
||||
{{ t("environment.initial_value") }}
|
||||
</span>
|
||||
<span
|
||||
class="min-w-[4rem] w-full truncate text-tiny font-semibold"
|
||||
>
|
||||
{{ t("environment.current_value") }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
|
|
@ -310,7 +326,13 @@
|
|||
<span class="min-w-[9rem] w-1/4 truncate text-secondaryLight">
|
||||
{{ variable.key }}
|
||||
</span>
|
||||
<span class="min-w-[9rem] w-full truncate text-secondaryLight">
|
||||
<span class="min-w-[4rem] w-full truncate text-secondaryLight">
|
||||
<template v-if="variable.secret"> ******** </template>
|
||||
<template v-else>
|
||||
{{ variable.initialValue }}
|
||||
</template>
|
||||
</span>
|
||||
<span class="min-w-[4rem] w-full truncate text-secondaryLight">
|
||||
<template v-if="variable.secret"> ******** </template>
|
||||
<template v-else>
|
||||
{{ variable.currentValue }}
|
||||
|
|
|
|||
|
|
@ -159,7 +159,11 @@ import * as A from "fp-ts/Array"
|
|||
import * as O from "fp-ts/Option"
|
||||
import * as TE from "fp-ts/TaskEither"
|
||||
import { flow, pipe } from "fp-ts/function"
|
||||
import { Environment, parseTemplateStringE } from "@hoppscotch/data"
|
||||
import {
|
||||
Environment,
|
||||
GlobalEnvironment,
|
||||
parseTemplateStringE,
|
||||
} from "@hoppscotch/data"
|
||||
import { refAutoReset } from "@vueuse/core"
|
||||
import { clone } from "lodash-es"
|
||||
import { useToast } from "@composables/toast"
|
||||
|
|
@ -181,6 +185,8 @@ import { useService } from "dioc/vue"
|
|||
import { SecretEnvironmentService } from "~/services/secret-environment.service"
|
||||
import { getEnvActionErrorMessage } from "~/helpers/error-messages"
|
||||
import { CurrentValueService } from "~/services/current-environment-value.service"
|
||||
import { useReadonlyStream } from "~/composables/stream"
|
||||
import { globalEnv$ } from "~/newstore/environments"
|
||||
|
||||
type EnvironmentVariable = {
|
||||
id: number
|
||||
|
|
@ -259,6 +265,8 @@ const vars = ref<EnvironmentVariable[]>([
|
|||
const secretEnvironmentService = useService(SecretEnvironmentService)
|
||||
const currentEnvironmentValueService = useService(CurrentValueService)
|
||||
|
||||
const globalEnv = useReadonlyStream(globalEnv$, {} as GlobalEnvironment)
|
||||
|
||||
const secretVars = computed(() =>
|
||||
pipe(
|
||||
vars.value,
|
||||
|
|
@ -302,6 +310,7 @@ const liveEnvs = computed(() => {
|
|||
}
|
||||
return [
|
||||
...vars.value.map((x) => ({ ...x.env, sourceEnv: editingName.value! })),
|
||||
...globalEnv.value.variables.map((x) => ({ ...x, sourceEnv: "Global" })),
|
||||
]
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
v-else
|
||||
ref="editor"
|
||||
:placeholder="placeholder"
|
||||
class="flex flex-1 truncate"
|
||||
class="flex flex-1 truncate relative"
|
||||
:class="styles"
|
||||
@click="emit('click', $event)"
|
||||
@keydown="handleKeystroke"
|
||||
|
|
@ -85,7 +85,10 @@ import { inputTheme } from "~/helpers/editor/themes/baseTheme"
|
|||
import { HoppReactiveEnvPlugin } from "~/helpers/editor/extensions/HoppEnvironment"
|
||||
import { HoppPredefinedVariablesPlugin } from "~/helpers/editor/extensions/HoppPredefinedVariables"
|
||||
import { useReadonlyStream } from "@composables/stream"
|
||||
import { AggregateEnvironment, aggregateEnvs$ } from "~/newstore/environments"
|
||||
import {
|
||||
AggregateEnvironment,
|
||||
aggregateEnvsWithCurrentValue$,
|
||||
} from "~/newstore/environments"
|
||||
import { platform } from "~/platform"
|
||||
import { onClickOutside, useDebounceFn } from "@vueuse/core"
|
||||
import { InspectorResult } from "~/services/inspection"
|
||||
|
|
@ -365,9 +368,10 @@ watch(
|
|||
let clipboardEv: ClipboardEvent | null = null
|
||||
let pastedValue: string | null = null
|
||||
|
||||
const aggregateEnvs = useReadonlyStream(aggregateEnvs$, []) as Ref<
|
||||
AggregateEnvironment[]
|
||||
>
|
||||
const aggregateEnvs = useReadonlyStream(
|
||||
aggregateEnvsWithCurrentValue$,
|
||||
[]
|
||||
) as Ref<AggregateEnvironment[]>
|
||||
|
||||
const tabs = useService(RESTTabService)
|
||||
|
||||
|
|
@ -377,7 +381,7 @@ const envVars = computed(() => {
|
|||
const { key, secret } = x
|
||||
const currentValue = secret ? "********" : x.currentValue
|
||||
const initialValue = secret ? "********" : x.initialValue
|
||||
const sourceEnv = "sourceEnv" in x ? x.sourceEnv : null
|
||||
const sourceEnv = "sourceEnv" in x ? x.sourceEnv : ""
|
||||
return {
|
||||
key,
|
||||
currentValue,
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ import { invokeAction } from "~/helpers/actions"
|
|||
import { getService } from "~/modules/dioc"
|
||||
import {
|
||||
AggregateEnvironment,
|
||||
aggregateEnvsWithSecrets$,
|
||||
getAggregateEnvs,
|
||||
aggregateEnvsWithCurrentValue$,
|
||||
getAggregateEnvsWithCurrentValue,
|
||||
getCurrentEnvironment,
|
||||
getSelectedEnvironmentType,
|
||||
} from "~/newstore/environments"
|
||||
|
|
@ -25,6 +25,8 @@ import { RESTTabService } from "~/services/tab/rest"
|
|||
import IconEdit from "~icons/lucide/edit?raw"
|
||||
import IconUser from "~icons/lucide/user?raw"
|
||||
import IconUsers from "~icons/lucide/users?raw"
|
||||
import IconGlobe from "~icons/lucide/globe?raw"
|
||||
import IconVariable from "~icons/lucide/variable?raw"
|
||||
import { isComment } from "./helpers"
|
||||
import { CurrentValueService } from "~/services/current-environment-value.service"
|
||||
|
||||
|
|
@ -121,49 +123,82 @@ const cursorTooltipField = (aggregateEnvs: AggregateEnvironment[]) =>
|
|||
|
||||
const envName = tooltipEnv?.sourceEnv ?? "Choose an Environment"
|
||||
|
||||
let envValue = "Not Found"
|
||||
const envTooltipValue =
|
||||
let envInitialValue = tooltipEnv?.initialValue
|
||||
|
||||
// If the environment is not a request variable, get the current value from the current environment service
|
||||
let envCurrentValue =
|
||||
tooltipEnv?.sourceEnv !== "RequestVariable"
|
||||
? (currentEnvironmentValueService.getEnvironmentByKey(
|
||||
? currentEnvironmentValueService.getEnvironmentByKey(
|
||||
tooltipEnv?.sourceEnv !== "Global"
|
||||
? currentSelectedEnvironment.id
|
||||
: "Global",
|
||||
tooltipEnv?.key ?? ""
|
||||
)?.currentValue ?? tooltipEnv?.currentValue)
|
||||
)?.currentValue || tooltipEnv?.currentValue
|
||||
: tooltipEnv?.currentValue
|
||||
|
||||
const hasSecretEnv = secretEnvironmentService.hasSecretValue(
|
||||
const isSecret = tooltipEnv?.secret === true
|
||||
const hasSource = Boolean(tooltipEnv?.sourceEnv)
|
||||
const hasSecretStored = secretEnvironmentService.hasSecretValue(
|
||||
tooltipEnv?.sourceEnv !== "Global"
|
||||
? currentSelectedEnvironment.id
|
||||
: "Global",
|
||||
tooltipEnv?.key ?? ""
|
||||
)
|
||||
|
||||
if (!tooltipEnv?.secret && envTooltipValue) {
|
||||
envValue = envTooltipValue
|
||||
} else if (tooltipEnv?.secret && hasSecretEnv) {
|
||||
envValue = "******"
|
||||
} else if (tooltipEnv?.secret && !hasSecretEnv) {
|
||||
envValue = "Empty"
|
||||
} else if (!tooltipEnv?.sourceEnv) {
|
||||
envValue = "Not Found"
|
||||
} else if (!envTooltipValue) {
|
||||
envValue = "Empty"
|
||||
// We need to check if the environment is a secret and if it has a secret value stored in the secret environment service
|
||||
// If it is a secret and has a secret value, we need to show "******" in the tooltip
|
||||
// If it is a secret and does not have a secret value, we need to show "Empty" in the tooltip
|
||||
// If it is not a secret, we need to show the current value or initial value
|
||||
// If the environment is not found, we need to show "Not Found" in the tooltip
|
||||
// If the source environment is not found, we need to show "Not Found" in the tooltip, ie the the environment
|
||||
// is not defined in the selected environment or the global environment
|
||||
if (isSecret) {
|
||||
if (!hasSecretStored && envInitialValue) {
|
||||
envInitialValue = "******"
|
||||
} else if (hasSecretStored && !envInitialValue) {
|
||||
envCurrentValue = "******"
|
||||
} else if (hasSecretStored && envInitialValue) {
|
||||
envInitialValue = "******"
|
||||
envCurrentValue = "******"
|
||||
} else {
|
||||
envInitialValue = "Empty"
|
||||
envCurrentValue = "Empty"
|
||||
}
|
||||
} else if (!hasSource) {
|
||||
envInitialValue = "Not Found"
|
||||
envCurrentValue = "Not Found"
|
||||
} else {
|
||||
// Parse templates only if needed and values are not already masked
|
||||
if (!envCurrentValue && envInitialValue) {
|
||||
const parsedInitial = parseTemplateStringE(
|
||||
envInitialValue,
|
||||
aggregateEnvs
|
||||
)
|
||||
envInitialValue = E.isLeft(parsedInitial)
|
||||
? "error"
|
||||
: parsedInitial.right
|
||||
} else if (!envInitialValue && envCurrentValue) {
|
||||
const parsedCurrent = parseTemplateStringE(
|
||||
envCurrentValue,
|
||||
aggregateEnvs
|
||||
)
|
||||
envCurrentValue = E.isLeft(parsedCurrent)
|
||||
? "error"
|
||||
: parsedCurrent.right
|
||||
}
|
||||
}
|
||||
|
||||
const result = parseTemplateStringE(envValue, aggregateEnvs)
|
||||
|
||||
let finalEnv = E.isLeft(result) ? "error" : result.right
|
||||
|
||||
// If the request variable has an secret variable
|
||||
// parseTemplateStringE is passed the secret value which has value undefined
|
||||
// So, we need to check if the result is undefined and then set the finalEnv to ******
|
||||
if (finalEnv === "undefined") finalEnv = "******"
|
||||
|
||||
const selectedEnvType = getSelectedEnvironmentType()
|
||||
|
||||
// Set the icon based on the source environment
|
||||
const envTypeIcon = `<span class="inline-flex items-center justify-center my-1">${
|
||||
selectedEnvType === "TEAM_ENV" ? IconUsers : IconUser
|
||||
tooltipEnv?.sourceEnv === "Global"
|
||||
? IconGlobe
|
||||
: tooltipEnv?.sourceEnv === "RequestVariable"
|
||||
? IconVariable
|
||||
: selectedEnvType === "TEAM_ENV"
|
||||
? IconUsers
|
||||
: IconUser
|
||||
}</span>`
|
||||
|
||||
const appendEditAction = (tooltip: HTMLElement) => {
|
||||
|
|
@ -205,22 +240,66 @@ const cursorTooltipField = (aggregateEnvs: AggregateEnvironment[]) =>
|
|||
}
|
||||
|
||||
return {
|
||||
pos: start,
|
||||
end: to,
|
||||
above: true,
|
||||
// The start and end positions of the environment variable in the text
|
||||
// We add 2 to the end position to include the closing `>>` in the tooltip
|
||||
// and -1 to the start position to include the opening `<<` in the tooltip
|
||||
pos: start - 1,
|
||||
end: end + 2,
|
||||
arrow: true,
|
||||
create() {
|
||||
const dom = document.createElement("span")
|
||||
const tooltipContainer = document.createElement("span")
|
||||
const kbd = document.createElement("kbd")
|
||||
const dom = document.createElement("div")
|
||||
|
||||
const tooltipContainer = document.createElement("div")
|
||||
|
||||
const tooltipHeaderBlock = document.createElement("div")
|
||||
tooltipHeaderBlock.className =
|
||||
"flex items-center justify-between w-full space-x-2 "
|
||||
tooltipContainer.appendChild(tooltipHeaderBlock)
|
||||
|
||||
const iconNameContainer = document.createElement("div")
|
||||
iconNameContainer.className =
|
||||
"flex items-center space-x-2 flex-1 mr-4 "
|
||||
tooltipHeaderBlock.appendChild(iconNameContainer)
|
||||
|
||||
const icon = document.createElement("span")
|
||||
icon.innerHTML = envTypeIcon
|
||||
icon.className = "mr-2"
|
||||
kbd.textContent = finalEnv
|
||||
tooltipContainer.appendChild(icon)
|
||||
tooltipContainer.appendChild(document.createTextNode(`${envName} `))
|
||||
tooltipContainer.appendChild(kbd)
|
||||
if (tooltipEnv) appendEditAction(tooltipContainer)
|
||||
|
||||
const envNameBlock = document.createElement("span")
|
||||
envNameBlock.innerText = envName
|
||||
|
||||
iconNameContainer.appendChild(icon)
|
||||
iconNameContainer.appendChild(envNameBlock)
|
||||
|
||||
if (tooltipEnv) appendEditAction(tooltipHeaderBlock)
|
||||
|
||||
const envContainer = document.createElement("div")
|
||||
tooltipContainer.appendChild(envContainer)
|
||||
envContainer.className =
|
||||
"flex flex-col items-start space-y-1 flex-1 w-full mt-2"
|
||||
|
||||
const initialValueBlock = document.createElement("div")
|
||||
initialValueBlock.className = "flex items-center space-x-2"
|
||||
const initialValueTitle = document.createElement("div")
|
||||
const initialValue = document.createElement("span")
|
||||
initialValue.textContent = envInitialValue || ""
|
||||
initialValueTitle.textContent = "Initial"
|
||||
initialValueTitle.className = "font-bold mr-4 "
|
||||
initialValueBlock.appendChild(initialValueTitle)
|
||||
initialValueBlock.appendChild(initialValue)
|
||||
|
||||
const currentValueBlock = document.createElement("div")
|
||||
currentValueBlock.className = "flex items-center space-x-2"
|
||||
const currentValueTitle = document.createElement("div")
|
||||
const currentValue = document.createElement("span")
|
||||
currentValue.textContent = envCurrentValue || ""
|
||||
currentValueTitle.textContent = "Current "
|
||||
currentValueTitle.className = "font-bold mr-1.5"
|
||||
currentValueBlock.appendChild(currentValueTitle)
|
||||
currentValueBlock.appendChild(currentValue)
|
||||
|
||||
envContainer.appendChild(initialValueBlock)
|
||||
envContainer.appendChild(currentValueBlock)
|
||||
|
||||
tooltipContainer.className = "tippy-content"
|
||||
dom.className = "tippy-box"
|
||||
dom.dataset.theme = "tooltip"
|
||||
|
|
@ -294,7 +373,7 @@ export class HoppEnvironmentPlugin {
|
|||
subscribeToStream: StreamSubscriberFunc,
|
||||
private editorView: Ref<EditorView | undefined>
|
||||
) {
|
||||
const aggregateEnvs = getAggregateEnvs()
|
||||
const aggregateEnvs = getAggregateEnvsWithCurrentValue()
|
||||
const currentTab = restTabs.currentActiveTab.value
|
||||
|
||||
const currentTabRequest =
|
||||
|
|
@ -302,6 +381,8 @@ export class HoppEnvironmentPlugin {
|
|||
? currentTab.document.response.originalRequest
|
||||
: currentTab.document.request
|
||||
|
||||
if (!currentTabRequest) return
|
||||
|
||||
watch(
|
||||
currentTabRequest,
|
||||
(request) => {
|
||||
|
|
@ -332,7 +413,7 @@ export class HoppEnvironmentPlugin {
|
|||
|
||||
const requestVariables = currentTabRequest?.requestVariables ?? []
|
||||
|
||||
subscribeToStream(aggregateEnvsWithSecrets$, (envs) => {
|
||||
subscribeToStream(aggregateEnvsWithCurrentValue$, (envs) => {
|
||||
this.envs = [
|
||||
...requestVariables.map(({ key, value }) => ({
|
||||
key,
|
||||
|
|
|
|||
|
|
@ -80,27 +80,58 @@ const cursorTooltipField = () =>
|
|||
: `${variableName} is not a valid predefined variable.`
|
||||
|
||||
return {
|
||||
pos: start,
|
||||
end: to,
|
||||
above: true,
|
||||
// The start and end positions of the environment variable in the text
|
||||
// We add 2 to the end position to include the closing `>>` in the tooltip
|
||||
// and -1 to the start position to include the opening `<<` in the tooltip
|
||||
pos: start - 1,
|
||||
end: end + 2,
|
||||
arrow: true,
|
||||
create() {
|
||||
const dom = document.createElement("div")
|
||||
dom.className = "tippy-box"
|
||||
dom.dataset.theme = "tooltip"
|
||||
|
||||
const tooltipContainer = document.createElement("div")
|
||||
|
||||
const tooltipHeaderBlock = document.createElement("div")
|
||||
tooltipHeaderBlock.className =
|
||||
"flex items-center justify-between w-full space-x-2 "
|
||||
tooltipContainer.appendChild(tooltipHeaderBlock)
|
||||
|
||||
const iconNameContainer = document.createElement("div")
|
||||
iconNameContainer.className =
|
||||
"flex items-center space-x-2 flex-1 mr-4 "
|
||||
tooltipHeaderBlock.appendChild(iconNameContainer)
|
||||
|
||||
const icon = document.createElement("span")
|
||||
icon.innerHTML = variableIcon
|
||||
icon.className = "mr-2"
|
||||
|
||||
const tooltipContainer = document.createElement("span")
|
||||
const envNameBlock = document.createElement("span")
|
||||
envNameBlock.innerText = variableName
|
||||
|
||||
iconNameContainer.appendChild(icon)
|
||||
iconNameContainer.appendChild(envNameBlock)
|
||||
|
||||
const envContainer = document.createElement("div")
|
||||
tooltipContainer.appendChild(envContainer)
|
||||
envContainer.className =
|
||||
"flex flex-col items-start space-y-1 flex-1 w-full mt-2"
|
||||
|
||||
const valueBlock = document.createElement("div")
|
||||
valueBlock.className = "flex items-center space-x-2"
|
||||
const valueTitle = document.createElement("div")
|
||||
const value = document.createElement("span")
|
||||
value.textContent = variableDescription || ""
|
||||
valueTitle.textContent = "Value"
|
||||
valueTitle.className = "font-bold mr-4 "
|
||||
valueBlock.appendChild(valueTitle)
|
||||
valueBlock.appendChild(value)
|
||||
|
||||
envContainer.appendChild(valueBlock)
|
||||
|
||||
dom.className = "tippy-box"
|
||||
dom.dataset.theme = "tooltip"
|
||||
|
||||
tooltipContainer.className = "tippy-content"
|
||||
|
||||
tooltipContainer.appendChild(icon)
|
||||
tooltipContainer.appendChild(
|
||||
document.createTextNode(variableDescription)
|
||||
)
|
||||
|
||||
dom.appendChild(tooltipContainer)
|
||||
return { dom }
|
||||
},
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import { getService } from "~/modules/dioc"
|
|||
import DispatchingStore, {
|
||||
defineDispatchers,
|
||||
} from "~/newstore/DispatchingStore"
|
||||
import { CurrentValueService } from "~/services/current-environment-value.service"
|
||||
import { SecretEnvironmentService } from "~/services/secret-environment.service"
|
||||
|
||||
export type SelectedEnvironmentIndex =
|
||||
|
|
@ -49,6 +50,7 @@ const defaultEnvironmentsState = {
|
|||
}
|
||||
|
||||
const secretEnvironmentService = getService(SecretEnvironmentService)
|
||||
const currentEnvironmentValueService = getService(CurrentValueService)
|
||||
|
||||
type EnvironmentStore = typeof defaultEnvironmentsState
|
||||
|
||||
|
|
@ -525,7 +527,7 @@ export function getAggregateEnvs() {
|
|||
]
|
||||
}
|
||||
|
||||
export function getAggregateEnvsWithSecrets() {
|
||||
export function getAggregateEnvsWithCurrentValue() {
|
||||
const currentEnv = getCurrentEnvironment()
|
||||
|
||||
return [
|
||||
|
|
@ -541,7 +543,11 @@ export function getAggregateEnvsWithSecrets() {
|
|||
|
||||
return <AggregateEnvironment>{
|
||||
key: x.key,
|
||||
currentValue,
|
||||
currentValue:
|
||||
currentEnvironmentValueService.getEnvironmentVariableValue(
|
||||
currentEnv.id,
|
||||
index
|
||||
) ?? currentValue,
|
||||
initialValue: x.initialValue,
|
||||
secret: x.secret,
|
||||
sourceEnv: currentEnv.name,
|
||||
|
|
@ -558,7 +564,11 @@ export function getAggregateEnvsWithSecrets() {
|
|||
}
|
||||
return <AggregateEnvironment>{
|
||||
key: x.key,
|
||||
currentValue,
|
||||
currentValue:
|
||||
currentEnvironmentValueService.getEnvironmentVariableValue(
|
||||
"Global",
|
||||
index
|
||||
) ?? currentValue,
|
||||
initialValue: x.initialValue,
|
||||
secret: x.secret,
|
||||
sourceEnv: "Global",
|
||||
|
|
@ -567,51 +577,71 @@ export function getAggregateEnvsWithSecrets() {
|
|||
]
|
||||
}
|
||||
|
||||
export const aggregateEnvsWithSecrets$: Observable<AggregateEnvironment[]> =
|
||||
combineLatest([currentEnvironment$, globalEnv$]).pipe(
|
||||
map(([selectedEnv, globalEnv]) => {
|
||||
const results: AggregateEnvironment[] = []
|
||||
export const aggregateEnvsWithCurrentValue$: Observable<
|
||||
AggregateEnvironment[]
|
||||
> = combineLatest([currentEnvironment$, globalEnv$]).pipe(
|
||||
map(([selectedEnv, globalEnv]) => {
|
||||
const results: AggregateEnvironment[] = []
|
||||
|
||||
selectedEnv?.variables.map((x, index) => {
|
||||
let currentValue = x.currentValue
|
||||
if (x.secret) {
|
||||
currentValue =
|
||||
secretEnvironmentService.getSecretEnvironmentVariableValue(
|
||||
selectedEnv.id,
|
||||
index
|
||||
) ?? ""
|
||||
}
|
||||
results.push({
|
||||
key: x.key,
|
||||
currentValue: currentValue,
|
||||
initialValue: x.initialValue,
|
||||
secret: x.secret,
|
||||
sourceEnv: selectedEnv.name,
|
||||
})
|
||||
// Ensure pre-defined variables are prioritised over other environment variables with the same name
|
||||
HOPP_SUPPORTED_PREDEFINED_VARIABLES.forEach(({ key, getValue }) => {
|
||||
results.push({
|
||||
key,
|
||||
currentValue: getValue(),
|
||||
initialValue: getValue(),
|
||||
secret: false,
|
||||
sourceEnv: selectedEnv?.name ?? "Global",
|
||||
})
|
||||
})
|
||||
|
||||
globalEnv.variables.map((x, index) => {
|
||||
let currentValue = x.currentValue
|
||||
if (x.secret) {
|
||||
currentValue =
|
||||
secretEnvironmentService.getSecretEnvironmentVariableValue(
|
||||
"Global",
|
||||
index
|
||||
) ?? ""
|
||||
}
|
||||
results.push({
|
||||
key: x.key,
|
||||
currentValue: currentValue,
|
||||
initialValue: x.initialValue,
|
||||
secret: x.secret,
|
||||
sourceEnv: "Global",
|
||||
})
|
||||
selectedEnv?.variables.map((x, index) => {
|
||||
let currentValue = x.currentValue
|
||||
if (x.secret) {
|
||||
currentValue =
|
||||
secretEnvironmentService.getSecretEnvironmentVariableValue(
|
||||
selectedEnv.id,
|
||||
index
|
||||
) ?? ""
|
||||
}
|
||||
results.push({
|
||||
key: x.key,
|
||||
currentValue:
|
||||
currentEnvironmentValueService.getEnvironmentVariableValue(
|
||||
selectedEnv.id,
|
||||
index
|
||||
) ?? currentValue,
|
||||
initialValue: x.initialValue,
|
||||
secret: x.secret,
|
||||
sourceEnv: selectedEnv.name,
|
||||
})
|
||||
})
|
||||
|
||||
return results
|
||||
}),
|
||||
distinctUntilChanged(isEqual)
|
||||
)
|
||||
globalEnv.variables.map((x, index) => {
|
||||
let currentValue = x.currentValue
|
||||
if (x.secret) {
|
||||
currentValue =
|
||||
secretEnvironmentService.getSecretEnvironmentVariableValue(
|
||||
"Global",
|
||||
index
|
||||
) ?? ""
|
||||
}
|
||||
results.push({
|
||||
key: x.key,
|
||||
currentValue:
|
||||
currentEnvironmentValueService.getEnvironmentVariableValue(
|
||||
"Global",
|
||||
index
|
||||
) ?? currentValue,
|
||||
initialValue: x.initialValue,
|
||||
secret: x.secret,
|
||||
sourceEnv: "Global",
|
||||
})
|
||||
})
|
||||
|
||||
return results
|
||||
}),
|
||||
distinctUntilChanged(isEqual)
|
||||
)
|
||||
|
||||
export function getCurrentEnvironment(): Environment {
|
||||
if (
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ vi.mock("~/newstore/environments", async () => {
|
|||
|
||||
return {
|
||||
__esModule: true,
|
||||
aggregateEnvsWithSecrets$: new BehaviorSubject([
|
||||
aggregateEnvsWithCurrentValue$: new BehaviorSubject([
|
||||
{
|
||||
key: "EXISTING_ENV_VAR",
|
||||
currentValue: "test_value",
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import {
|
|||
} from "@hoppscotch/data"
|
||||
import {
|
||||
AggregateEnvironment,
|
||||
aggregateEnvsWithSecrets$,
|
||||
aggregateEnvsWithCurrentValue$,
|
||||
getCurrentEnvironment,
|
||||
getSelectedEnvironmentType,
|
||||
} from "~/newstore/environments"
|
||||
|
|
@ -50,8 +50,8 @@ export class EnvironmentInspectorService extends Service implements Inspector {
|
|||
private readonly currentEnvs = this.bind(CurrentValueService)
|
||||
private readonly restTabs = this.bind(RESTTabService)
|
||||
|
||||
private aggregateEnvsWithSecrets = useStreamStatic(
|
||||
aggregateEnvsWithSecrets$,
|
||||
private aggregateEnvsWithValue = useStreamStatic(
|
||||
aggregateEnvsWithCurrentValue$,
|
||||
[],
|
||||
() => {
|
||||
/* noop */
|
||||
|
|
@ -85,7 +85,7 @@ export class EnvironmentInspectorService extends Service implements Inspector {
|
|||
|
||||
const environmentVariables = [
|
||||
...(currentTabRequest?.requestVariables ?? []),
|
||||
...this.aggregateEnvsWithSecrets.value,
|
||||
...this.aggregateEnvsWithValue.value,
|
||||
]
|
||||
|
||||
const envKeys = environmentVariables.map((e) => e.key)
|
||||
|
|
@ -171,7 +171,7 @@ export class EnvironmentInspectorService extends Service implements Inspector {
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks if the environment variables in the target array are empty
|
||||
* Checks if the environment variables in the target have empty current value or initial value.
|
||||
* @param target The target array to validate
|
||||
* @param locations The location where results are to be displayed
|
||||
* @returns The results array containing the results of the validation
|
||||
|
|
@ -210,7 +210,7 @@ export class EnvironmentInspectorService extends Service implements Inspector {
|
|||
secret: false,
|
||||
sourceEnv: "RequestVariable",
|
||||
})),
|
||||
...this.aggregateEnvsWithSecrets.value,
|
||||
...this.aggregateEnvsWithValue.value,
|
||||
])
|
||||
|
||||
environmentVariables.forEach((env) => {
|
||||
|
|
@ -221,16 +221,18 @@ export class EnvironmentInspectorService extends Service implements Inspector {
|
|||
env.key
|
||||
)
|
||||
|
||||
const hasCurrentValue =
|
||||
const hasValue =
|
||||
this.currentEnvs.hasValue(
|
||||
env.sourceEnv !== "Global"
|
||||
? currentSelectedEnvironment.id
|
||||
: "Global",
|
||||
env.key
|
||||
) || env.currentValue !== ""
|
||||
) ||
|
||||
env.currentValue !== "" ||
|
||||
env.initialValue !== ""
|
||||
|
||||
if (env.key === formattedExEnv) {
|
||||
if (env.secret ? !hasSecretEnv : !hasCurrentValue) {
|
||||
if (env.secret ? !hasSecretEnv : !hasValue) {
|
||||
const itemLocation: InspectorLocation = {
|
||||
type: locations.type,
|
||||
position:
|
||||
|
|
|
|||
|
|
@ -102,13 +102,7 @@ export const parseBodyEnvVariables = (
|
|||
|
||||
export function parseTemplateStringE(
|
||||
str: string,
|
||||
variables:
|
||||
| Environment["variables"]
|
||||
| {
|
||||
secret: true
|
||||
currentValue: string
|
||||
key: string
|
||||
}[],
|
||||
variables: Environment["variables"],
|
||||
maskValue = false,
|
||||
showKeyIfSecret = false
|
||||
) {
|
||||
|
|
@ -183,13 +177,7 @@ export type NonSecretEnvironment = Omit<Environment, "variables"> & {
|
|||
*/
|
||||
export const parseTemplateString = (
|
||||
str: string,
|
||||
variables:
|
||||
| Environment["variables"]
|
||||
| {
|
||||
secret: true
|
||||
currentValue: string
|
||||
key: string
|
||||
}[],
|
||||
variables: Environment["variables"],
|
||||
maskValue = false,
|
||||
showKeyIfSecret = false
|
||||
) =>
|
||||
|
|
|
|||
Loading…
Reference in a new issue