Files
hoppscotch/packages/hoppscotch-selfhost-web/src/platform/environments/environments.platform.ts
2024-02-08 21:58:42 +05:30

203 lines
5.4 KiB
TypeScript

import { authEvents$, def as platformAuth } from "@platform/auth/auth.platform"
import {
createEnvironment,
deleteEnvironment,
environmentsStore,
getLocalIndexByEnvironmentID,
replaceEnvironments,
setGlobalEnvID,
setGlobalEnvVariables,
updateEnvironment,
} from "@hoppscotch/common/newstore/environments"
import { EnvironmentsPlatformDef } from "@hoppscotch/common/src/platform/environments"
import { runGQLSubscription } from "@hoppscotch/common/helpers/backend/GQLClient"
import { environnmentsSyncer } from "@platform/environments/environments.sync"
import * as E from "fp-ts/Either"
import { runDispatchWithOutSyncing } from "@lib/sync"
import {
createUserGlobalEnvironment,
getGlobalEnvironments,
getUserEnvironments,
runUserEnvironmentCreatedSubscription,
runUserEnvironmentDeletedSubscription,
runUserEnvironmentUpdatedSubscription,
} from "@platform/environments/environments.api"
export function initEnvironmentsSync() {
const currentUser$ = platformAuth.getCurrentUserStream()
environnmentsSyncer.startStoreSync()
environnmentsSyncer.setupSubscriptions(setupSubscriptions)
currentUser$.subscribe(async (user) => {
if (user) {
await loadAllEnvironments()
}
})
authEvents$.subscribe((event) => {
if (event.event == "login" || event.event == "token_refresh") {
environnmentsSyncer.startListeningToSubscriptions()
}
if (event.event == "logout") {
environnmentsSyncer.stopListeningToSubscriptions()
}
})
}
export const def: EnvironmentsPlatformDef = {
initEnvironmentsSync,
}
function setupSubscriptions() {
let subs: ReturnType<typeof runGQLSubscription>[1][] = []
const userEnvironmentCreatedSub = setupUserEnvironmentCreatedSubscription()
const userEnvironmentUpdatedSub = setupUserEnvironmentUpdatedSubscription()
const userEnvironmentDeletedSub = setupUserEnvironmentDeletedSubscription()
subs = [
userEnvironmentCreatedSub,
userEnvironmentUpdatedSub,
userEnvironmentDeletedSub,
]
return () => {
subs.forEach((sub) => sub.unsubscribe())
}
}
async function loadUserEnvironments() {
const res = await getUserEnvironments()
if (E.isRight(res)) {
const environments = res.right.me.environments
if (environments.length > 0) {
runDispatchWithOutSyncing(() => {
replaceEnvironments(
environments.map(({ id, variables, name }) => ({
v: 1,
id,
name,
variables: JSON.parse(variables),
}))
)
})
}
}
}
async function loadGlobalEnvironments() {
const res = await getGlobalEnvironments()
if (E.isRight(res)) {
const globalEnv = res.right.me.globalEnvironments
if (globalEnv) {
runDispatchWithOutSyncing(() => {
setGlobalEnvVariables(JSON.parse(globalEnv.variables))
setGlobalEnvID(globalEnv.id)
})
}
} else if (res.left.error == "user_environment/user_env_does_not_exists") {
const res = await createUserGlobalEnvironment(JSON.stringify([]))
if (E.isRight(res)) {
const backendId = res.right.createUserGlobalEnvironment.id
setGlobalEnvID(backendId)
}
}
}
async function loadAllEnvironments() {
await loadUserEnvironments()
await loadGlobalEnvironments()
}
function setupUserEnvironmentCreatedSubscription() {
const [userEnvironmentCreated$, userEnvironmentCreatedSub] =
runUserEnvironmentCreatedSubscription()
userEnvironmentCreated$.subscribe((res) => {
if (E.isRight(res)) {
const { name, variables, id } = res.right.userEnvironmentCreated
const isAlreadyExisting = environmentsStore.value.environments.some(
(env) => env.id == id
)
if (name && !isAlreadyExisting) {
runDispatchWithOutSyncing(() => {
createEnvironment(name, JSON.parse(variables), id)
})
}
}
})
return userEnvironmentCreatedSub
}
function setupUserEnvironmentUpdatedSubscription() {
const [userEnvironmentUpdated$, userEnvironmentUpdatedSub] =
runUserEnvironmentUpdatedSubscription()
userEnvironmentUpdated$.subscribe((res) => {
if (E.isRight(res)) {
const { name, variables, id, isGlobal } = res.right.userEnvironmentUpdated
// handle the case for global environments
if (isGlobal) {
runDispatchWithOutSyncing(() => {
setGlobalEnvVariables(JSON.parse(variables))
})
} else {
// handle the case for normal environments
const localIndex = environmentsStore.value.environments.findIndex(
(env) => env.id == id
)
if ((localIndex || localIndex == 0) && name) {
runDispatchWithOutSyncing(() => {
updateEnvironment(localIndex, {
v: 1,
id,
name,
variables: JSON.parse(variables),
})
})
}
}
}
})
return userEnvironmentUpdatedSub
}
function setupUserEnvironmentDeletedSubscription() {
const [userEnvironmentDeleted$, userEnvironmentDeletedSub] =
runUserEnvironmentDeletedSubscription()
userEnvironmentDeleted$.subscribe((res) => {
if (E.isRight(res)) {
const { id } = res.right.userEnvironmentDeleted
// TODO: move getLocalIndexByID to a getter in the environmentsStore
const localIndex = getLocalIndexByEnvironmentID(id)
if (localIndex || localIndex === 0) {
runDispatchWithOutSyncing(() => {
deleteEnvironment(localIndex)
})
}
}
})
return userEnvironmentDeletedSub
}