Files
hoppscotch/packages/hoppscotch-common/src/helpers/collection/collection.ts

235 lines
6.8 KiB
TypeScript

import { HoppCollection, HoppRESTRequest } from "@hoppscotch/data"
import { getAffectedIndexes } from "./affectedIndex"
import { GetSingleRequestDocument } from "../backend/graphql"
import { runGQLQuery } from "../backend/GQLClient"
import * as E from "fp-ts/Either"
import { getService } from "~/modules/dioc"
import { RESTTabService } from "~/services/tab/rest"
import { HoppInheritedProperty } from "../types/HoppInheritedProperties"
import { GQLTabService } from "~/services/tab/graphql"
/**
* Resolve save context on reorder
* @param payload
* @param payload.lastIndex
* @param payload.newIndex
* @param folderPath
* @param payload.length
* @returns
*/
export function resolveSaveContextOnCollectionReorder(
payload: {
lastIndex: number
newIndex: number
folderPath: string
length?: number // better way to do this? now it could be undefined
},
type: "remove" | "drop" = "remove"
) {
const { lastIndex, folderPath, length } = payload
let { newIndex } = payload
if (newIndex > lastIndex) newIndex-- // there is a issue when going down? better way to resolve this?
if (lastIndex === newIndex) return
const affectedIndexes = getAffectedIndexes(
lastIndex,
newIndex === -1 ? length! : newIndex
)
if (newIndex === -1) {
// if (newIndex === -1) remove it from the map because it will be deleted
affectedIndexes.delete(lastIndex)
// when collection deleted opended requests from that collection be affected
if (type === "remove") {
resetSaveContextForAffectedRequests(
folderPath ? `${folderPath}/${lastIndex}` : lastIndex.toString()
)
}
}
// add folder path as prefix to the affected indexes
const affectedPaths = new Map<string, string>()
for (const [key, value] of affectedIndexes) {
if (folderPath) {
affectedPaths.set(`${folderPath}/${key}`, `${folderPath}/${value}`)
} else {
affectedPaths.set(key.toString(), value.toString())
}
}
const tabService = getService(RESTTabService)
const tabs = tabService.getTabsRefTo((tab) => {
return (
tab.document.saveContext?.originLocation === "user-collection" &&
affectedPaths.has(tab.document.saveContext.folderPath)
)
})
for (const tab of tabs) {
if (tab.value.document.saveContext?.originLocation === "user-collection") {
const newPath = affectedPaths.get(
tab.value.document.saveContext?.folderPath
)!
tab.value.document.saveContext.folderPath = newPath
}
}
}
/**
* Resolve save context for affected requests on drop folder from one to another
* @param oldFolderPath
* @param newFolderPath
* @returns
*/
export function updateSaveContextForAffectedRequests(
oldFolderPath: string,
newFolderPath: string
) {
const tabService = getService(RESTTabService)
const tabs = tabService.getTabsRefTo((tab) => {
return (
tab.document.saveContext?.originLocation === "user-collection" &&
tab.document.saveContext.folderPath.startsWith(oldFolderPath)
)
})
for (const tab of tabs) {
if (tab.value.document.saveContext?.originLocation === "user-collection") {
tab.value.document.saveContext = {
...tab.value.document.saveContext,
folderPath: tab.value.document.saveContext.folderPath.replace(
oldFolderPath,
newFolderPath
),
}
}
}
}
export function updateInheritedPropertiesForAffectedRequests(
path: string,
inheritedProperties: HoppInheritedProperty,
type: "rest" | "graphql"
) {
const tabService =
type === "rest" ? getService(RESTTabService) : getService(GQLTabService)
const tabs = tabService.getTabsRefTo((tab) => {
return (
tab.document.saveContext?.originLocation === "user-collection" &&
tab.document.saveContext.folderPath.startsWith(path)
)
})
const tabsEffectedByAuth = tabs.filter((tab) => {
return (
tab.value.document.inheritedProperties &&
tab.value.document.inheritedProperties.auth.parentID === path
)
})
const tabsEffectedByHeaders = tabs.filter((tab) => {
return (
tab.value.document.inheritedProperties &&
tab.value.document.inheritedProperties.headers.some(
(header) => header.parentID === path
)
)
})
for (const tab of tabsEffectedByAuth) {
tab.value.document.inheritedProperties = inheritedProperties
}
for (const tab of tabsEffectedByHeaders) {
const headers = tab.value.document.inheritedProperties?.headers.map(
(header) => {
if (header.parentID === path) {
return {
...header,
inheritedHeader: inheritedProperties.headers.find(
(inheritedHeader) =>
inheritedHeader.inheritedHeader?.key ===
header.inheritedHeader?.key
)?.inheritedHeader,
}
}
return header
}
)
tab.value.document.inheritedProperties = {
...tab.value.document.inheritedProperties,
headers,
}
}
}
function resetSaveContextForAffectedRequests(folderPath: string) {
const tabService = getService(RESTTabService)
const tabs = tabService.getTabsRefTo((tab) => {
return (
tab.document.saveContext?.originLocation === "user-collection" &&
tab.document.saveContext.folderPath.startsWith(folderPath)
)
})
for (const tab of tabs) {
tab.value.document.saveContext = null
tab.value.document.isDirty = true
}
}
/**
* Reset save context to null if requests are deleted from the team collection or its folder
* only runs when collection or folder is deleted
*/
export async function resetTeamRequestsContext() {
const tabService = getService(RESTTabService)
const tabs = tabService.getTabsRefTo((tab) => {
return tab.document.saveContext?.originLocation === "team-collection"
})
for (const tab of tabs) {
if (tab.value.document.saveContext?.originLocation === "team-collection") {
const data = await runGQLQuery({
query: GetSingleRequestDocument,
variables: {
requestID: tab.value.document.saveContext?.requestID,
},
})
if (E.isRight(data) && data.right.request === null) {
tab.value.document.saveContext = null
tab.value.document.isDirty = true
}
}
}
}
export function getFoldersByPath(
collections: HoppCollection<HoppRESTRequest>[],
path: string
): HoppCollection<HoppRESTRequest>[] {
if (!path) return collections
// path will be like this "0/0/1" these are the indexes of the folders
const pathArray = path.split("/").map((index) => parseInt(index))
let currentCollection = collections[pathArray[0]]
if (pathArray.length === 1) {
return currentCollection.folders
}
for (let i = 1; i < pathArray.length; i++) {
const folder = currentCollection.folders[pathArray[i]]
if (folder) currentCollection = folder
}
return currentCollection.folders
}