feat: collection level headers and authorization (#3505)

Co-authored-by: Andrew Bastin <andrewbastin.k@gmail.com>
This commit is contained in:
Nivedin
2023-12-13 22:43:18 +05:30
committed by GitHub
parent f3edd001d7
commit 47e009267b
95 changed files with 3221 additions and 970 deletions

View File

@@ -10,23 +10,34 @@ 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: [
makeCollection<HoppRESTRequest>({
makeCollection({
name: "My Collection",
folders: [],
requests: [],
auth: {
authType: "inherit",
authActive: false,
},
headers: [],
}),
],
}
const defaultGraphqlCollectionState = {
state: [
makeCollection<HoppGQLRequest>({
makeCollection({
name: "My GraphQL Collection",
folders: [],
requests: [],
auth: {
authType: "inherit",
authActive: false,
},
headers: [],
}),
],
}
@@ -39,7 +50,7 @@ type GraphqlCollectionStoreType = typeof defaultGraphqlCollectionState
* Not removing this behaviour because i'm not sure if we utilize this behaviour anywhere and i found this on a tight time crunch.
*/
export function navigateToFolderWithIndexPath(
collections: HoppCollection<HoppRESTRequest | HoppGQLRequest>[],
collections: HoppCollection[],
indexPaths: number[]
) {
if (indexPaths.length === 0) return null
@@ -52,6 +63,94 @@ export function navigateToFolderWithIndexPath(
return target !== undefined ? target : null
}
export function cascadeParentCollectionForHeaderAuth(
folderPath: string | undefined,
type: "rest" | "graphql"
) {
const collectionStore =
type === "rest" ? restCollectionStore : graphqlCollectionStore
let auth: HoppInheritedProperty["auth"] = {
parentID: folderPath ?? "",
parentName: "",
inheritedAuth: {
authType: "none",
authActive: true,
},
}
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 }
}
// Loop through the path and get the last parent folder with authType other than 'inherit'
for (let i = 0; i < path.length; i++) {
const parentFolder = navigateToFolderWithIndexPath(
collectionStore.value.state,
[...path.slice(0, i + 1)] // Create a copy of the path array
)
// Check if parentFolder is undefined or null
if (!parentFolder) {
console.error("Parent folder not found for path:", path)
return { auth, headers }
}
const parentFolderAuth = parentFolder.auth
const parentFolderHeaders = parentFolder.headers
// check if the parent folder has authType 'inherit' and if it is the root folder
if (parentFolderAuth?.authType === "inherit" && path.length === 1) {
auth = {
parentID: [...path.slice(0, i + 1)].join("/"),
parentName: parentFolder.name,
inheritedAuth: auth.inheritedAuth,
}
}
if (parentFolderAuth?.authType !== "inherit") {
auth = {
parentID: [...path.slice(0, i + 1)].join("/"),
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.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] = {
parentID: currentPath,
parentName: parentFolder.name,
inheritedHeader: header,
}
} else {
headers.push({
parentID: currentPath,
parentName: parentFolder.name,
inheritedHeader: header,
})
}
})
}
}
return { auth, headers }
}
function reorderItems(array: unknown[], from: number, to: number) {
const item = array.splice(from, 1)[0]
if (from < to) {
@@ -64,7 +163,7 @@ function reorderItems(array: unknown[], from: number, to: number) {
const restCollectionDispatchers = defineDispatchers({
setCollections(
_: RESTCollectionStoreType,
{ entries }: { entries: HoppCollection<HoppRESTRequest>[] }
{ entries }: { entries: HoppCollection[] }
) {
return {
state: entries,
@@ -73,7 +172,7 @@ const restCollectionDispatchers = defineDispatchers({
appendCollections(
{ state }: RESTCollectionStoreType,
{ entries }: { entries: HoppCollection<HoppRESTRequest>[] }
{ entries }: { entries: HoppCollection[] }
) {
return {
state: [...state, ...entries],
@@ -82,7 +181,7 @@ const restCollectionDispatchers = defineDispatchers({
addCollection(
{ state }: RESTCollectionStoreType,
{ collection }: { collection: HoppCollection<any> }
{ collection }: { collection: HoppCollection }
) {
return {
state: [...state, collection],
@@ -112,7 +211,7 @@ const restCollectionDispatchers = defineDispatchers({
partialCollection,
}: {
collectionIndex: number
partialCollection: Partial<HoppCollection<any>>
partialCollection: Partial<HoppCollection>
}
) {
return {
@@ -128,10 +227,15 @@ const restCollectionDispatchers = defineDispatchers({
{ state }: RESTCollectionStoreType,
{ name, path }: { name: string; path: string }
) {
const newFolder: HoppCollection<HoppRESTRequest> = makeCollection({
const newFolder: HoppCollection = makeCollection({
name,
folders: [],
requests: [],
auth: {
authType: "inherit",
authActive: true,
},
headers: [],
})
const newState = state
@@ -158,7 +262,7 @@ const restCollectionDispatchers = defineDispatchers({
folder,
}: {
path: string
folder: Partial<HoppCollection<HoppRESTRequest>>
folder: Partial<HoppCollection>
}
) {
const newState = state
@@ -249,7 +353,7 @@ const restCollectionDispatchers = defineDispatchers({
}
const theFolder = containingFolder.folders.splice(folderIndex, 1)
newState.push(theFolder[0] as HoppCollection<HoppRESTRequest>)
newState.push(theFolder[0] as HoppCollection)
return {
state: newState,
@@ -612,7 +716,7 @@ const restCollectionDispatchers = defineDispatchers({
type: "collection" | "request"
}
) {
const after = removeDuplicateCollectionsFromPath<HoppRESTRequest>(
const after = removeDuplicateCollectionsFromPath(
id,
collectionPath,
state,
@@ -628,7 +732,7 @@ const restCollectionDispatchers = defineDispatchers({
const gqlCollectionDispatchers = defineDispatchers({
setCollections(
_: GraphqlCollectionStoreType,
{ entries }: { entries: HoppCollection<any>[] }
{ entries }: { entries: HoppCollection[] }
) {
return {
state: entries,
@@ -637,7 +741,7 @@ const gqlCollectionDispatchers = defineDispatchers({
appendCollections(
{ state }: GraphqlCollectionStoreType,
{ entries }: { entries: HoppCollection<any>[] }
{ entries }: { entries: HoppCollection[] }
) {
return {
state: [...state, ...entries],
@@ -646,7 +750,7 @@ const gqlCollectionDispatchers = defineDispatchers({
addCollection(
{ state }: GraphqlCollectionStoreType,
{ collection }: { collection: HoppCollection<any> }
{ collection }: { collection: HoppCollection }
) {
return {
state: [...state, collection],
@@ -673,7 +777,7 @@ const gqlCollectionDispatchers = defineDispatchers({
{
collectionIndex,
collection,
}: { collectionIndex: number; collection: Partial<HoppCollection<any>> }
}: { collectionIndex: number; collection: Partial<HoppCollection> }
) {
return {
state: state.map((col, index) =>
@@ -686,12 +790,16 @@ const gqlCollectionDispatchers = defineDispatchers({
{ state }: GraphqlCollectionStoreType,
{ name, path }: { name: string; path: string }
) {
const newFolder: HoppCollection<HoppGQLRequest> = makeCollection({
const newFolder: HoppCollection = makeCollection({
name,
folders: [],
requests: [],
auth: {
authType: "inherit",
authActive: true,
},
headers: [],
})
const newState = state
const indexPaths = path.split("/").map((x) => parseInt(x))
@@ -711,10 +819,7 @@ const gqlCollectionDispatchers = defineDispatchers({
editFolder(
{ state }: GraphqlCollectionStoreType,
{
path,
folder,
}: { path: string; folder: Partial<HoppCollection<HoppGQLRequest>> }
{ path, folder }: { path: string; folder: Partial<HoppCollection> }
) {
const newState = state
@@ -913,7 +1018,7 @@ const gqlCollectionDispatchers = defineDispatchers({
type: "collection" | "request"
}
) {
const after = removeDuplicateCollectionsFromPath<HoppGQLRequest>(
const after = removeDuplicateCollectionsFromPath(
id,
collectionPath,
state,
@@ -936,7 +1041,7 @@ export const graphqlCollectionStore = new DispatchingStore(
gqlCollectionDispatchers
)
export function setRESTCollections(entries: HoppCollection<HoppRESTRequest>[]) {
export function setRESTCollections(entries: HoppCollection[]) {
restCollectionStore.dispatch({
dispatcher: "setCollections",
payload: {
@@ -953,9 +1058,7 @@ export const graphqlCollections$ = graphqlCollectionStore.subject$.pipe(
pluck("state")
)
export function appendRESTCollections(
entries: HoppCollection<HoppRESTRequest>[]
) {
export function appendRESTCollections(entries: HoppCollection[]) {
restCollectionStore.dispatch({
dispatcher: "appendCollections",
payload: {
@@ -964,7 +1067,7 @@ export function appendRESTCollections(
})
}
export function addRESTCollection(collection: HoppCollection<HoppRESTRequest>) {
export function addRESTCollection(collection: HoppCollection) {
restCollectionStore.dispatch({
dispatcher: "addCollection",
payload: {
@@ -992,7 +1095,7 @@ export function getRESTCollection(collectionIndex: number) {
export function editRESTCollection(
collectionIndex: number,
partialCollection: Partial<HoppCollection<HoppRESTRequest>>
partialCollection: Partial<HoppCollection>
) {
restCollectionStore.dispatch({
dispatcher: "editCollection",
@@ -1013,10 +1116,7 @@ export function addRESTFolder(name: string, path: string) {
})
}
export function editRESTFolder(
path: string,
folder: Partial<HoppCollection<HoppRESTRequest>>
) {
export function editRESTFolder(path: string, folder: Partial<HoppCollection>) {
restCollectionStore.dispatch({
dispatcher: "editFolder",
payload: {
@@ -1160,9 +1260,7 @@ export function updateRESTCollectionOrder(
})
}
export function setGraphqlCollections(
entries: HoppCollection<HoppGQLRequest>[]
) {
export function setGraphqlCollections(entries: HoppCollection[]) {
graphqlCollectionStore.dispatch({
dispatcher: "setCollections",
payload: {
@@ -1171,9 +1269,7 @@ export function setGraphqlCollections(
})
}
export function appendGraphqlCollections(
entries: HoppCollection<HoppGQLRequest>[]
) {
export function appendGraphqlCollections(entries: HoppCollection[]) {
graphqlCollectionStore.dispatch({
dispatcher: "appendCollections",
payload: {
@@ -1182,9 +1278,7 @@ export function appendGraphqlCollections(
})
}
export function addGraphqlCollection(
collection: HoppCollection<HoppGQLRequest>
) {
export function addGraphqlCollection(collection: HoppCollection) {
graphqlCollectionStore.dispatch({
dispatcher: "addCollection",
payload: {
@@ -1208,7 +1302,7 @@ export function removeGraphqlCollection(
export function editGraphqlCollection(
collectionIndex: number,
collection: Partial<HoppCollection<HoppGQLRequest>>
collection: Partial<HoppCollection>
) {
graphqlCollectionStore.dispatch({
dispatcher: "editCollection",
@@ -1231,7 +1325,7 @@ export function addGraphqlFolder(name: string, path: string) {
export function editGraphqlFolder(
path: string,
folder: Partial<HoppCollection<HoppGQLRequest>>
folder: Partial<HoppCollection>
) {
graphqlCollectionStore.dispatch({
dispatcher: "editFolder",
@@ -1322,14 +1416,12 @@ export function moveGraphqlRequest(
})
}
function removeDuplicateCollectionsFromPath<
T extends HoppRESTRequest | HoppGQLRequest,
>(
function removeDuplicateCollectionsFromPath(
idToRemove: string,
collectionPath: string | null,
collections: HoppCollection<T>[],
collections: HoppCollection[],
type: "collection" | "request"
): HoppCollection<T>[] {
): HoppCollection[] {
const indexes = collectionPath?.split("/").map((x) => parseInt(x))
indexes && indexes.pop()
const parentPath = indexes?.join("/")