From 0a54455fe72d94ed73572e3f18190ebed592ef8e Mon Sep 17 00:00:00 2001 From: nivedin Date: Thu, 30 Nov 2023 19:43:46 +0530 Subject: [PATCH] refactor: inherit header from multiple collecions --- .../src/components/collections/Properties.vue | 6 +- .../src/components/collections/index.vue | 29 +++------- .../src/components/http/Authorization.vue | 9 ++- .../src/components/http/Headers.vue | 31 +++++----- .../src/helpers/RequestRunner.ts | 26 +++++++-- .../src/helpers/collection/collection.ts | 38 +++++++++++- .../helpers/types/HoppInheritedProperties.ts | 14 +++-- .../src/helpers/utils/EffectiveURL.ts | 23 ++++---- .../src/newstore/collections.ts | 58 ++++++++++++------- 9 files changed, 145 insertions(+), 89 deletions(-) diff --git a/packages/hoppscotch-common/src/components/collections/Properties.vue b/packages/hoppscotch-common/src/components/collections/Properties.vue index 76d617aab..7384f2074 100644 --- a/packages/hoppscotch-common/src/components/collections/Properties.vue +++ b/packages/hoppscotch-common/src/components/collections/Properties.vue @@ -40,8 +40,8 @@ (null) @@ -678,7 +679,7 @@ const onAddRequest = (requestName: string) => { if (!path) return const insertionIndex = saveRESTRequestAs(path, newRequest) - const { auth, headers, name } = cascaseParentCollectionForHeaderAuth(path) + const { auth, headers } = cascaseParentCollectionForHeaderAuth(path) tabs.createNewTab({ request: newRequest, @@ -691,8 +692,6 @@ const onAddRequest = (requestName: string) => { inheritedProperties: { auth, headers, - parentName: name, - parentId: path, }, }) @@ -1330,8 +1329,7 @@ const selectRequest = (selectedRequest: { // If there is a request with this save context, switch into it let possibleTab = null - const { auth, headers, name } = - cascaseParentCollectionForHeaderAuth(folderPath) + const { auth, headers } = cascaseParentCollectionForHeaderAuth(folderPath) if (collectionsType.value.type === "team-collections") { possibleTab = tabs.getTabRefWithSaveContext({ @@ -1369,9 +1367,7 @@ const selectRequest = (selectedRequest: { requestIndex: parseInt(requestIndex), }, inheritedProperties: { - parentId: folderPath || "", - parentName: name, - auth: auth, + auth, headers, }, }) @@ -1405,7 +1401,7 @@ const dropRequest = (payload: { let possibleTab = null if (collectionsType.value.type === "my-collections" && folderPath) { - const { auth, headers, name } = cascaseParentCollectionForHeaderAuth( + const { auth, headers } = cascaseParentCollectionForHeaderAuth( destinationCollectionIndex ) @@ -1427,8 +1423,6 @@ const dropRequest = (payload: { } possibleTab.value.document.inheritedProperties = { - parentId: destinationCollectionIndex, - parentName: name, auth, headers, } @@ -1600,13 +1594,11 @@ const dropCollection = (payload: { `${destinationCollectionIndex}/${totalFoldersOfDestinationCollection}` ) - const { auth, headers, name } = cascaseParentCollectionForHeaderAuth( + const { auth, headers } = cascaseParentCollectionForHeaderAuth( `${destinationCollectionIndex}/${totalFoldersOfDestinationCollection}` ) const inheritedProperty = { - parentId: `${destinationCollectionIndex}/${totalFoldersOfDestinationCollection}`, - parentName: name, auth, headers, } @@ -1983,12 +1975,9 @@ const editProperties = (payload: { let inheritedProperties = {} if (parentIndex) { - const { auth, headers, name } = - cascaseParentCollectionForHeaderAuth(parentIndex) + const { auth, headers } = cascaseParentCollectionForHeaderAuth(parentIndex) inheritedProperties = { - parentId: parentIndex ?? "", - parentName: name, auth, headers, } as HoppInheritedProperty @@ -2016,12 +2005,10 @@ const setCollectionProperties = (newCollection: { editRESTFolder(path, collection) } - const { auth, headers, name } = cascaseParentCollectionForHeaderAuth(path) + const { auth, headers } = cascaseParentCollectionForHeaderAuth(path) nextTick(() => { updateInheritedPropertiesForAffectedRequests(path, { - parentId: path, - parentName: name, auth, headers, }) diff --git a/packages/hoppscotch-common/src/components/http/Authorization.vue b/packages/hoppscotch-common/src/components/http/Authorization.vue index e76504b5b..8a802bae6 100644 --- a/packages/hoppscotch-common/src/components/http/Authorization.vue +++ b/packages/hoppscotch-common/src/components/http/Authorization.vue @@ -155,8 +155,8 @@
Inherited - {{ getAuthName(inheritedProperties.auth.authType) }} from Parent - Collection {{ inheritedProperties?.parentName }} + {{ getAuthName(inheritedProperties.auth.inheritedAuth.authType) }} + from Parent Collection {{ inheritedProperties?.auth.parentName }} Please save this request in any collection to inherit the @@ -232,7 +232,10 @@ const auth = useVModel(props, "modelValue", emit) onMounted(() => { if (props.isRootCollection && auth.value.authType === "inherit") { console.log("isRootCollection", auth.value.authType) - auth.value.authType = "none" + auth.value = { + authType: "none", + authActive: true, + } } }) diff --git a/packages/hoppscotch-common/src/components/http/Headers.vue b/packages/hoppscotch-common/src/components/http/Headers.vue index b8009cfda..2e1c0ee2e 100644 --- a/packages/hoppscotch-common/src/components/http/Headers.vue +++ b/packages/hoppscotch-common/src/components/http/Headers.vue @@ -242,17 +242,14 @@ :placeholder="`${t('count.value', { count: index + 1 })}`" readonly /> - - - + + { ) const headers = inheritedHeaders.map((header, index) => ({ - inheritedFrom: props.inheritedProperties?.parentName, + inheritedFrom: props.inheritedProperties?.headers[index].parentName, source: "headers", id: `header-${index}`, header: { - key: header.key, - value: header.value, - active: header.active, + key: header.inheritedHeader?.key, + value: header.inheritedHeader?.value, + active: header.inheritedHeader?.active, }, })) @@ -602,7 +599,7 @@ const inheritedProperties = computed(() => { const computedAuthHeader = getComputedAuthHeaders( aggregateEnvs.value, request.value, - props.inheritedProperties.auth + props.inheritedProperties.auth.inheritedAuth )[0] if ( @@ -612,7 +609,7 @@ const inheritedProperties = computed(() => { ) { auth = [ { - inheritedFrom: props.inheritedProperties?.parentName, + inheritedFrom: props.inheritedProperties?.auth.parentName, source: "auth", id: `header-auth`, header: computedAuthHeader, diff --git a/packages/hoppscotch-common/src/helpers/RequestRunner.ts b/packages/hoppscotch-common/src/helpers/RequestRunner.ts index 843728e12..7e1c473a8 100644 --- a/packages/hoppscotch-common/src/helpers/RequestRunner.ts +++ b/packages/hoppscotch-common/src/helpers/RequestRunner.ts @@ -98,17 +98,31 @@ export function runRESTRequest$( const requestAuth = tab.value.document.request.auth.authType === "inherit" && tab.value.document.request.auth.authActive - ? tab.value.document.inheritedProperties?.auth + ? tab.value.document.inheritedProperties?.auth.inheritedAuth : tab.value.document.request.auth - const requestHeaders = [ - ...(tab.value.document.inheritedProperties?.headers ?? []), - ...tab.value.document.request.headers, - ] + let requestHeaders + + const inheritedHeaders = + tab.value.document.inheritedProperties?.headers.map((header) => { + if (header.inheritedHeader) { + return header.inheritedHeader + } + return [] + }) + + if (inheritedHeaders) { + requestHeaders = [ + ...inheritedHeaders, + ...tab.value.document.request.headers, + ] + } else { + requestHeaders = [...tab.value.document.request.headers] + } const finalRequest = { ...tab.value.document.request, - auth: requestAuth, + auth: requestAuth ?? { authType: "none", authActive: false }, headers: requestHeaders, } diff --git a/packages/hoppscotch-common/src/helpers/collection/collection.ts b/packages/hoppscotch-common/src/helpers/collection/collection.ts index 245b9203d..0fabd6040 100644 --- a/packages/hoppscotch-common/src/helpers/collection/collection.ts +++ b/packages/hoppscotch-common/src/helpers/collection/collection.ts @@ -121,16 +121,48 @@ export function updateInheritedPropertiesForAffectedRequests( ) }) - const filteredTabs = tabs.filter((tab) => { + const tabsEffectedByAuth = tabs.filter((tab) => { return ( tab.value.document.inheritedProperties && - tab.value.document.inheritedProperties.parentId === path + tab.value.document.inheritedProperties.auth.parentID === path ) }) - for (const tab of filteredTabs) { + 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) { diff --git a/packages/hoppscotch-common/src/helpers/types/HoppInheritedProperties.ts b/packages/hoppscotch-common/src/helpers/types/HoppInheritedProperties.ts index 98df1fbb3..100619bf9 100644 --- a/packages/hoppscotch-common/src/helpers/types/HoppInheritedProperties.ts +++ b/packages/hoppscotch-common/src/helpers/types/HoppInheritedProperties.ts @@ -1,8 +1,14 @@ import { HoppRESTRequest } from "@hoppscotch/data" export type HoppInheritedProperty = { - parentId: string - parentName: string - auth?: HoppRESTRequest["auth"] - headers?: HoppRESTRequest["headers"] + auth: { + parentID: string + parentName: string + inheritedAuth: HoppRESTRequest["auth"] + } + headers: { + parentID: string + parentName: string + inheritedHeader?: HoppRESTRequest["headers"][number] + }[] } diff --git a/packages/hoppscotch-common/src/helpers/utils/EffectiveURL.ts b/packages/hoppscotch-common/src/helpers/utils/EffectiveURL.ts index f0b5b49b4..353c12f0c 100644 --- a/packages/hoppscotch-common/src/helpers/utils/EffectiveURL.ts +++ b/packages/hoppscotch-common/src/helpers/utils/EffectiveURL.ts @@ -48,7 +48,6 @@ export const getComputedAuthHeaders = ( auth?: HoppRESTRequest["auth"] ) => { const request = auth ? { auth: auth ?? { authActive: false } } : req - // If Authorization header is also being user-defined, that takes priority if (req && req.headers.find((h) => h.key.toLowerCase() === "authorization")) return [] @@ -136,16 +135,18 @@ export type ComputedHeader = { export const getComputedHeaders = ( req: HoppRESTRequest, envVars: Environment["variables"] -): ComputedHeader[] => [ - ...getComputedAuthHeaders(envVars, req).map((header) => ({ - source: "auth" as const, - header, - })), - ...getComputedBodyHeaders(req).map((header) => ({ - source: "body" as const, - header, - })), -] +): ComputedHeader[] => { + return [ + ...getComputedAuthHeaders(envVars, req).map((header) => ({ + source: "auth" as const, + header, + })), + ...getComputedBodyHeaders(req).map((header) => ({ + source: "body" as const, + header, + })), + ] +} export type ComputedParam = { source: "auth" diff --git a/packages/hoppscotch-common/src/newstore/collections.ts b/packages/hoppscotch-common/src/newstore/collections.ts index 55f31cdef..c9100e926 100644 --- a/packages/hoppscotch-common/src/newstore/collections.ts +++ b/packages/hoppscotch-common/src/newstore/collections.ts @@ -10,6 +10,7 @@ import { cloneDeep } from "lodash-es" import { resolveSaveContextOnRequestReorder } from "~/helpers/collection/request" import { getService } from "~/modules/dioc" import { RESTTabService } from "~/services/tab/rest" +import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties" const defaultRESTCollectionState = { state: [ @@ -65,19 +66,22 @@ export function navigateToFolderWithIndexPath( export function cascaseParentCollectionForHeaderAuth( folderPath: string | undefined ) { - let auth: HoppRESTRequest["auth"] = { - authType: "none", - authActive: false, + let auth: HoppInheritedProperty["auth"] = { + parentID: folderPath ?? "", + parentName: "", + inheritedAuth: { + authType: "inherit", + authActive: false, + }, } - const headers: HoppRESTRequest["headers"] = [] - let name = "" - if (!folderPath) return { auth, headers, name: "" } + const headers: HoppInheritedProperty["headers"] = [] + if (!folderPath) return { auth, headers } const path = folderPath.split("/").map((i) => parseInt(i)) // Check if the path is empty or invalid if (!path || path.length === 0) { console.error("Invalid path:", folderPath) - return { auth, headers, name: "" } + return { auth, headers } } // Loop through the path and get the last parent folder with authType other than 'inherit' @@ -90,33 +94,49 @@ export function cascaseParentCollectionForHeaderAuth( // Check if parentFolder is undefined or null if (!parentFolder) { console.error("Parent folder not found for path:", path) - return { auth, headers, name: "" } + return { auth, headers } } const parentFolderAuth = parentFolder.auth const parentFolderHeaders = parentFolder.headers + const isRootCollection = path.length === 1 + // Check if authType is not 'inherit' - if (parentFolderAuth?.authType !== "inherit") { - auth = parentFolderAuth || auth - name = parentFolder.name + if (parentFolderAuth?.authType !== "inherit" || isRootCollection) { + auth = { + parentID: parentFolder.id ?? folderPath, + parentName: parentFolder.name, + inheritedAuth: parentFolderAuth, + } } // Update headers, overwriting duplicates by key if (parentFolderHeaders) { const activeHeaders = parentFolderHeaders.filter((h) => h.active) activeHeaders.forEach((header) => { - const index = headers.findIndex((h) => h.key === header.key) + const index = headers.findIndex( + (h) => h.inheritedHeader?.key === header.key + ) + const currentPath = [...path.slice(0, i + 1)].join("/") if (index !== -1) { // Replace the existing header with the same key - headers[index] = header + headers[index] = { + parentID: currentPath, + parentName: parentFolder.name, + inheritedHeader: header, + } } else { - headers.push(header) + headers.push({ + parentID: currentPath, + parentName: parentFolder.name, + inheritedHeader: header, + }) } }) } } - return { auth, headers, name } + return { auth, headers } } function reorderItems(array: unknown[], from: number, to: number) { @@ -201,11 +221,7 @@ const restCollectionDispatchers = defineDispatchers({ requests: [], auth: { authType: "inherit", - authActive: false, - auth: { - authType: "inherit", - authActive: false, - }, + authActive: true, }, headers: [], }) @@ -768,7 +784,7 @@ const gqlCollectionDispatchers = defineDispatchers({ requests: [], auth: { authType: "inherit", - authActive: false, + authActive: true, }, headers: [], })