feat: collection level headers and authorization (#3505)
Co-authored-by: Andrew Bastin <andrewbastin.k@gmail.com>
This commit is contained in:
@@ -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("/")
|
||||
|
||||
Reference in New Issue
Block a user