chore: merge hoppscotch/staging into self-hosted/main
This commit is contained in:
@@ -31,9 +31,9 @@
|
||||
"@codemirror/state": "^6.1.0",
|
||||
"@codemirror/view": "^6.0.2",
|
||||
"@hoppscotch/codemirror-lang-graphql": "workspace:^0.2.0",
|
||||
"@hoppscotch/ui": "workspace:^0.0.1",
|
||||
"@hoppscotch/data": "workspace:^0.4.4",
|
||||
"@hoppscotch/js-sandbox": "workspace:^2.1.0",
|
||||
"@hoppscotch/ui": "workspace:^0.0.1",
|
||||
"@hoppscotch/vue-toasted": "^0.1.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@sentry/tracing": "^7.13.0",
|
||||
@@ -125,6 +125,7 @@
|
||||
"@vue/eslint-config-typescript": "^11.0.1",
|
||||
"@vue/runtime-core": "^3.2.39",
|
||||
"cross-env": "^7.0.3",
|
||||
"dotenv": "^16.0.3",
|
||||
"eslint": "^8.24.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-vue": "^9.5.1",
|
||||
|
||||
@@ -89,7 +89,6 @@ declare module '@vue/runtime-core' {
|
||||
HoppSmartSpinner: typeof import('@hoppscotch/ui')['HoppSmartSpinner']
|
||||
HoppSmartTab: typeof import('@hoppscotch/ui')['HoppSmartTab']
|
||||
HoppSmartTabs: typeof import('@hoppscotch/ui')['HoppSmartTabs']
|
||||
HoppSmartToggle: typeof import('@hoppscotch/ui')['HoppSmartToggle']
|
||||
HttpAuthorization: typeof import('./components/http/Authorization.vue')['default']
|
||||
HttpBody: typeof import('./components/http/Body.vue')['default']
|
||||
HttpBodyParameters: typeof import('./components/http/BodyParameters.vue')['default']
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
class="h-1 w-full transition"
|
||||
:class="[
|
||||
{
|
||||
'bg-accentDark': ordering && notSameDestination,
|
||||
'bg-accentDark': isReorderable,
|
||||
},
|
||||
]"
|
||||
@drop="orderUpdateCollectionEvent"
|
||||
@@ -20,35 +20,43 @@
|
||||
}"
|
||||
></div>
|
||||
<div
|
||||
class="flex items-stretch group relative z-3"
|
||||
class="flex items-stretch group relative z-3 cursor-pointer pointer-events-auto"
|
||||
:draggable="!hasNoTeamAccess"
|
||||
@dragstart="dragStart"
|
||||
@drop="dropEvent"
|
||||
@dragover="dragging = true"
|
||||
@dragleave="dragging = false"
|
||||
@dragend="resetDragState"
|
||||
@drop="handelDrop($event)"
|
||||
@dragover="handleDragOver($event)"
|
||||
@dragleave="resetDragState"
|
||||
@dragend="
|
||||
() => {
|
||||
resetDragState()
|
||||
dropItemID = ''
|
||||
}
|
||||
"
|
||||
@contextmenu.prevent="options?.tippy.show()"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-center px-4 cursor-pointer"
|
||||
<div
|
||||
class="flex items-center justify-center flex-1 min-w-0"
|
||||
@click="emit('toggle-children')"
|
||||
>
|
||||
<HoppSmartSpinner v-if="isCollLoading" />
|
||||
<component
|
||||
:is="collectionIcon"
|
||||
v-else
|
||||
class="svg-icons"
|
||||
:class="{ 'text-accent': isSelected }"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer group-hover:text-secondaryDark"
|
||||
@click="emit('toggle-children')"
|
||||
>
|
||||
<span class="truncate" :class="{ 'text-accent': isSelected }">
|
||||
{{ collectionName }}
|
||||
<span
|
||||
class="flex items-center justify-center px-4 pointer-events-none"
|
||||
>
|
||||
<HoppSmartSpinner v-if="isCollLoading" />
|
||||
<component
|
||||
:is="collectionIcon"
|
||||
v-else
|
||||
class="svg-icons"
|
||||
:class="{ 'text-accent': isSelected }"
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="flex flex-1 min-w-0 py-2 pr-2 transition pointer-events-none group-hover:text-secondaryDark"
|
||||
>
|
||||
<span class="truncate" :class="{ 'text-accent': isSelected }">
|
||||
{{ collectionName }}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="!hasNoTeamAccess" class="flex">
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
@@ -175,6 +183,11 @@ import { HoppCollection, HoppRESTRequest } from "@hoppscotch/data"
|
||||
import { useI18n } from "@composables/i18n"
|
||||
import { TippyComponent } from "vue-tippy"
|
||||
import { TeamCollection } from "~/helpers/teams/TeamCollection"
|
||||
import {
|
||||
changeCurrentReorderStatus,
|
||||
currentReorderingStatus$,
|
||||
} from "~/newstore/reordering"
|
||||
import { useReadonlyStream } from "~/composables/stream"
|
||||
|
||||
type CollectionType = "my-collections" | "team-collections"
|
||||
type FolderType = "collection" | "folder"
|
||||
@@ -187,6 +200,11 @@ const props = defineProps({
|
||||
default: "",
|
||||
required: true,
|
||||
},
|
||||
parentID: {
|
||||
type: String as PropType<string | null>,
|
||||
default: null,
|
||||
required: true,
|
||||
},
|
||||
data: {
|
||||
type: Object as PropType<HoppCollection<HoppRESTRequest> | TeamCollection>,
|
||||
default: () => ({}),
|
||||
@@ -258,6 +276,12 @@ const dragging = ref(false)
|
||||
const ordering = ref(false)
|
||||
const dropItemID = ref("")
|
||||
|
||||
const currentReorderingStatus = useReadonlyStream(currentReorderingStatus$, {
|
||||
type: "collection",
|
||||
id: "",
|
||||
parentID: "",
|
||||
})
|
||||
|
||||
// Used to determine if the collection is being dragged to a different destination
|
||||
// This is used to make the highlight effect work
|
||||
watch(
|
||||
@@ -293,11 +317,52 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
const isRequestDragging = computed(() => {
|
||||
return currentReorderingStatus.value.type === "request"
|
||||
})
|
||||
|
||||
const isSameParent = computed(() => {
|
||||
return currentReorderingStatus.value.parentID === props.parentID
|
||||
})
|
||||
|
||||
const isReorderable = computed(() => {
|
||||
return (
|
||||
ordering.value &&
|
||||
notSameDestination.value &&
|
||||
!isRequestDragging.value &&
|
||||
isSameParent.value
|
||||
)
|
||||
})
|
||||
|
||||
const dragStart = ({ dataTransfer }: DragEvent) => {
|
||||
if (dataTransfer) {
|
||||
emit("drag-event", dataTransfer)
|
||||
dropItemID.value = dataTransfer.getData("collectionIndex")
|
||||
dragging.value = !dragging.value
|
||||
changeCurrentReorderStatus({
|
||||
type: "collection",
|
||||
id: props.id,
|
||||
parentID: props.parentID,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger the re-ordering event when a collection is dragged over another collection's top section
|
||||
const handleDragOver = (e: DragEvent) => {
|
||||
dragging.value = true
|
||||
if (e.offsetY < 10 && notSameDestination.value) {
|
||||
ordering.value = true
|
||||
dragging.value = false
|
||||
} else {
|
||||
ordering.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handelDrop = (e: DragEvent) => {
|
||||
if (ordering.value) {
|
||||
orderUpdateCollectionEvent(e)
|
||||
} else {
|
||||
dropEvent(e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,8 +370,7 @@ const dropEvent = (e: DragEvent) => {
|
||||
if (e.dataTransfer) {
|
||||
e.stopPropagation()
|
||||
emit("drop-event", e.dataTransfer)
|
||||
dragging.value = !dragging.value
|
||||
dropItemID.value = ""
|
||||
resetDragState()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,8 +378,7 @@ const orderUpdateCollectionEvent = (e: DragEvent) => {
|
||||
if (e.dataTransfer) {
|
||||
e.stopPropagation()
|
||||
emit("update-collection-order", e.dataTransfer)
|
||||
ordering.value = !ordering.value
|
||||
dropItemID.value = ""
|
||||
resetDragState()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,6 +397,5 @@ const isCollLoading = computed(() => {
|
||||
const resetDragState = () => {
|
||||
dragging.value = false
|
||||
ordering.value = false
|
||||
dropItemID.value = ""
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
<CollectionsCollection
|
||||
v-if="node.data.type === 'collections'"
|
||||
:id="node.id"
|
||||
:parent-i-d="node.data.data.parentIndex"
|
||||
:data="node.data.data.data"
|
||||
:collections-type="collectionsType.type"
|
||||
:is-open="isOpen"
|
||||
@@ -94,6 +95,7 @@
|
||||
<CollectionsCollection
|
||||
v-if="node.data.type === 'folders'"
|
||||
:id="node.id"
|
||||
:parent-i-d="node.data.data.parentIndex"
|
||||
:data="node.data.data.data"
|
||||
:collections-type="collectionsType.type"
|
||||
:is-open="isOpen"
|
||||
@@ -149,6 +151,8 @@
|
||||
<CollectionsRequest
|
||||
v-if="node.data.type === 'requests'"
|
||||
:request="node.data.data.data"
|
||||
:request-i-d="node.id"
|
||||
:parent-i-d="node.data.data.parentIndex"
|
||||
:collections-type="collectionsType.type"
|
||||
:save-request="saveRequest"
|
||||
:is-active="
|
||||
|
||||
@@ -4,61 +4,65 @@
|
||||
class="h-1"
|
||||
:class="[
|
||||
{
|
||||
'bg-accentDark': ordering,
|
||||
'bg-accentDark': isReorderable,
|
||||
},
|
||||
]"
|
||||
@drop="dropEvent"
|
||||
@dragover.prevent="ordering = true"
|
||||
@dragleave="ordering = false"
|
||||
@dragend="ordering = false"
|
||||
@dragleave="resetDragState"
|
||||
@dragend="resetDragState"
|
||||
></div>
|
||||
<div
|
||||
class="flex items-stretch group"
|
||||
:draggable="!hasNoTeamAccess"
|
||||
@drop="dropEvent"
|
||||
@dragstart="dragStart"
|
||||
@dragover.prevent="dragging = true"
|
||||
@dragleave="dragging = false"
|
||||
@dragend="dragging = false"
|
||||
@dragover="handleDragOver($event)"
|
||||
@dragleave="resetDragState"
|
||||
@dragend="resetDragState"
|
||||
@contextmenu.prevent="options?.tippy.show()"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-center w-16 px-2 truncate cursor-pointer"
|
||||
:class="requestLabelColor"
|
||||
<div
|
||||
class="flex items-center justify-center flex-1 min-w-0 cursor-pointer pointer-events-auto"
|
||||
@click="selectRequest()"
|
||||
>
|
||||
<component
|
||||
:is="IconCheckCircle"
|
||||
v-if="isSelected"
|
||||
class="svg-icons"
|
||||
:class="{ 'text-accent': isSelected }"
|
||||
/>
|
||||
<HoppSmartSpinner v-else-if="isRequestLoading" />
|
||||
<span v-else class="font-semibold truncate text-tiny">
|
||||
{{ request.method }}
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="flex items-center flex-1 min-w-0 py-2 pr-2 cursor-pointer transition group-hover:text-secondaryDark"
|
||||
@click="selectRequest()"
|
||||
>
|
||||
<span class="truncate" :class="{ 'text-accent': isSelected }">
|
||||
{{ request.name }}
|
||||
<span
|
||||
class="flex items-center justify-center w-16 px-2 truncate pointer-events-none"
|
||||
:class="requestLabelColor"
|
||||
>
|
||||
<component
|
||||
:is="IconCheckCircle"
|
||||
v-if="isSelected"
|
||||
class="svg-icons"
|
||||
:class="{ 'text-accent': isSelected }"
|
||||
/>
|
||||
<HoppSmartSpinner v-else-if="isRequestLoading" />
|
||||
<span v-else class="font-semibold truncate text-tiny">
|
||||
{{ request.method }}
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
v-if="isActive"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
class="relative h-1.5 w-1.5 flex flex-shrink-0 mx-3"
|
||||
:title="`${t('collection.request_in_use')}`"
|
||||
class="flex items-center flex-1 min-w-0 py-2 pr-2 pointer-events-none transition group-hover:text-secondaryDark"
|
||||
>
|
||||
<span
|
||||
class="absolute inline-flex flex-shrink-0 w-full h-full bg-green-500 rounded-full opacity-75 animate-ping"
|
||||
>
|
||||
<span class="truncate" :class="{ 'text-accent': isSelected }">
|
||||
{{ request.name }}
|
||||
</span>
|
||||
<span
|
||||
class="relative inline-flex flex-shrink-0 rounded-full h-1.5 w-1.5 bg-green-500"
|
||||
></span>
|
||||
v-if="isActive"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
class="relative h-1.5 w-1.5 flex flex-shrink-0 mx-3"
|
||||
:title="`${t('collection.request_in_use')}`"
|
||||
>
|
||||
<span
|
||||
class="absolute inline-flex flex-shrink-0 w-full h-full bg-green-500 rounded-full opacity-75 animate-ping"
|
||||
>
|
||||
</span>
|
||||
<span
|
||||
class="relative inline-flex flex-shrink-0 rounded-full h-1.5 w-1.5 bg-green-500"
|
||||
></span>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="!hasNoTeamAccess" class="flex">
|
||||
<HoppButtonSecondary
|
||||
v-if="!saveRequest"
|
||||
@@ -151,6 +155,11 @@ import { TippyComponent } from "vue-tippy"
|
||||
import { pipe } from "fp-ts/function"
|
||||
import * as RR from "fp-ts/ReadonlyRecord"
|
||||
import * as O from "fp-ts/Option"
|
||||
import {
|
||||
changeCurrentReorderStatus,
|
||||
currentReorderingStatus$,
|
||||
} from "~/newstore/reordering"
|
||||
import { useReadonlyStream } from "~/composables/stream"
|
||||
|
||||
type CollectionType = "my-collections" | "team-collections"
|
||||
|
||||
@@ -167,6 +176,11 @@ const props = defineProps({
|
||||
default: "",
|
||||
required: false,
|
||||
},
|
||||
parentID: {
|
||||
type: String as PropType<string | null>,
|
||||
default: null,
|
||||
required: true,
|
||||
},
|
||||
collectionsType: {
|
||||
type: String as PropType<CollectionType>,
|
||||
default: "my-collections",
|
||||
@@ -222,6 +236,12 @@ const duplicate = ref<HTMLButtonElement | null>(null)
|
||||
const dragging = ref(false)
|
||||
const ordering = ref(false)
|
||||
|
||||
const currentReorderingStatus = useReadonlyStream(currentReorderingStatus$, {
|
||||
type: "collection",
|
||||
id: "",
|
||||
parentID: "",
|
||||
})
|
||||
|
||||
const requestMethodLabels = {
|
||||
get: "text-green-500",
|
||||
post: "text-yellow-500",
|
||||
@@ -255,13 +275,41 @@ const dragStart = ({ dataTransfer }: DragEvent) => {
|
||||
if (dataTransfer) {
|
||||
emit("drag-request", dataTransfer)
|
||||
dragging.value = !dragging.value
|
||||
changeCurrentReorderStatus({
|
||||
type: "request",
|
||||
id: props.requestID,
|
||||
parentID: props.parentID,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const isCollectionDragging = computed(() => {
|
||||
return currentReorderingStatus.value.type === "collection"
|
||||
})
|
||||
|
||||
const isSameParent = computed(() => {
|
||||
return currentReorderingStatus.value.parentID === props.parentID
|
||||
})
|
||||
|
||||
const isReorderable = computed(() => {
|
||||
return ordering.value && !isCollectionDragging.value && isSameParent.value
|
||||
})
|
||||
|
||||
// Trigger the re-ordering event when a request is dragged over another request's top section
|
||||
const handleDragOver = (e: DragEvent) => {
|
||||
dragging.value = true
|
||||
if (e.offsetY < 10) {
|
||||
ordering.value = true
|
||||
dragging.value = false
|
||||
} else {
|
||||
ordering.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const dropEvent = (e: DragEvent) => {
|
||||
if (e.dataTransfer) {
|
||||
e.stopPropagation()
|
||||
ordering.value = !ordering.value
|
||||
resetDragState()
|
||||
emit("update-request-order", e.dataTransfer)
|
||||
}
|
||||
}
|
||||
@@ -273,4 +321,9 @@ const isRequestLoading = computed(() => {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
const resetDragState = () => {
|
||||
dragging.value = false
|
||||
ordering.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
<CollectionsCollection
|
||||
v-if="node.data.type === 'collections'"
|
||||
:id="node.data.data.data.id"
|
||||
:parent-i-d="node.data.data.parentIndex"
|
||||
:data="node.data.data.data"
|
||||
:collections-type="collectionsType.type"
|
||||
:is-open="isOpen"
|
||||
@@ -114,6 +115,7 @@
|
||||
<CollectionsCollection
|
||||
v-if="node.data.type === 'folders'"
|
||||
:id="node.data.data.data.id"
|
||||
:parent-i-d="node.data.data.parentIndex"
|
||||
:data="node.data.data.data"
|
||||
:collections-type="collectionsType.type"
|
||||
:is-open="isOpen"
|
||||
@@ -178,6 +180,7 @@
|
||||
v-if="node.data.type === 'requests'"
|
||||
:request="node.data.data.data.request"
|
||||
:request-i-d="node.data.data.data.id"
|
||||
:parent-i-d="node.data.data.parentIndex"
|
||||
:collections-type="collectionsType.type"
|
||||
:duplicate-loading="duplicateLoading"
|
||||
:is-active="isActiveRequest(node.data.data.data.id)"
|
||||
|
||||
@@ -209,7 +209,7 @@ import {
|
||||
setRESTRequest,
|
||||
setRESTSaveContext,
|
||||
} from "~/newstore/RESTSession"
|
||||
import { cloneDeep } from "lodash-es"
|
||||
import { cloneDeep, isEqual } from "lodash-es"
|
||||
import { GQLError } from "~/helpers/backend/GQLClient"
|
||||
import {
|
||||
createNewRootCollection,
|
||||
@@ -470,62 +470,60 @@ const filteredCollections = computed(() => {
|
||||
return filteredCollections
|
||||
})
|
||||
|
||||
const isSelected = computed(() => {
|
||||
return ({
|
||||
collectionIndex,
|
||||
folderPath,
|
||||
requestIndex,
|
||||
collectionID,
|
||||
folderID,
|
||||
requestID,
|
||||
}: {
|
||||
collectionIndex?: number | undefined
|
||||
folderPath?: string | undefined
|
||||
requestIndex?: number | undefined
|
||||
collectionID?: string | undefined
|
||||
folderID?: string | undefined
|
||||
requestID?: string | undefined
|
||||
}) => {
|
||||
if (collectionIndex !== undefined) {
|
||||
return (
|
||||
props.picked &&
|
||||
props.picked.pickedType === "my-collection" &&
|
||||
props.picked.collectionIndex === collectionIndex
|
||||
)
|
||||
} else if (requestIndex !== undefined && folderPath !== undefined) {
|
||||
return (
|
||||
props.picked &&
|
||||
props.picked.pickedType === "my-request" &&
|
||||
props.picked.folderPath === folderPath &&
|
||||
props.picked.requestIndex === requestIndex
|
||||
)
|
||||
} else if (folderPath !== undefined) {
|
||||
return (
|
||||
props.picked &&
|
||||
props.picked.pickedType === "my-folder" &&
|
||||
props.picked.folderPath === folderPath
|
||||
)
|
||||
} else if (collectionID !== undefined) {
|
||||
return (
|
||||
props.picked &&
|
||||
props.picked.pickedType === "teams-collection" &&
|
||||
props.picked.collectionID === collectionID
|
||||
)
|
||||
} else if (requestID !== undefined) {
|
||||
return (
|
||||
props.picked &&
|
||||
props.picked.pickedType === "teams-request" &&
|
||||
props.picked.requestID === requestID
|
||||
)
|
||||
} else if (folderID !== undefined) {
|
||||
return (
|
||||
props.picked &&
|
||||
props.picked.pickedType === "teams-folder" &&
|
||||
props.picked.folderID === folderID
|
||||
)
|
||||
}
|
||||
const isSelected = ({
|
||||
collectionIndex,
|
||||
folderPath,
|
||||
requestIndex,
|
||||
collectionID,
|
||||
folderID,
|
||||
requestID,
|
||||
}: {
|
||||
collectionIndex?: number | undefined
|
||||
folderPath?: string | undefined
|
||||
requestIndex?: number | undefined
|
||||
collectionID?: string | undefined
|
||||
folderID?: string | undefined
|
||||
requestID?: string | undefined
|
||||
}) => {
|
||||
if (collectionIndex !== undefined) {
|
||||
return (
|
||||
props.picked &&
|
||||
props.picked.pickedType === "my-collection" &&
|
||||
props.picked.collectionIndex === collectionIndex
|
||||
)
|
||||
} else if (requestIndex !== undefined && folderPath !== undefined) {
|
||||
return (
|
||||
props.picked &&
|
||||
props.picked.pickedType === "my-request" &&
|
||||
props.picked.folderPath === folderPath &&
|
||||
props.picked.requestIndex === requestIndex
|
||||
)
|
||||
} else if (folderPath !== undefined) {
|
||||
return (
|
||||
props.picked &&
|
||||
props.picked.pickedType === "my-folder" &&
|
||||
props.picked.folderPath === folderPath
|
||||
)
|
||||
} else if (collectionID !== undefined) {
|
||||
return (
|
||||
props.picked &&
|
||||
props.picked.pickedType === "teams-collection" &&
|
||||
props.picked.collectionID === collectionID
|
||||
)
|
||||
} else if (requestID !== undefined) {
|
||||
return (
|
||||
props.picked &&
|
||||
props.picked.pickedType === "teams-request" &&
|
||||
props.picked.requestID === requestID
|
||||
)
|
||||
} else if (folderID !== undefined) {
|
||||
return (
|
||||
props.picked &&
|
||||
props.picked.pickedType === "teams-folder" &&
|
||||
props.picked.folderID === folderID
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const modalLoadingState = ref(false)
|
||||
const exportLoading = ref(false)
|
||||
@@ -1023,7 +1021,7 @@ const onRemoveCollection = () => {
|
||||
if (collectionIndex === null) return
|
||||
|
||||
if (
|
||||
isSelected.value({
|
||||
isSelected({
|
||||
collectionIndex,
|
||||
})
|
||||
) {
|
||||
@@ -1040,7 +1038,7 @@ const onRemoveCollection = () => {
|
||||
if (!collectionID) return
|
||||
|
||||
if (
|
||||
isSelected.value({
|
||||
isSelected({
|
||||
collectionID,
|
||||
})
|
||||
) {
|
||||
@@ -1067,7 +1065,7 @@ const onRemoveFolder = () => {
|
||||
if (!folderPath) return
|
||||
|
||||
if (
|
||||
isSelected.value({
|
||||
isSelected({
|
||||
folderPath,
|
||||
})
|
||||
) {
|
||||
@@ -1084,7 +1082,7 @@ const onRemoveFolder = () => {
|
||||
if (!collectionID) return
|
||||
|
||||
if (
|
||||
isSelected.value({
|
||||
isSelected({
|
||||
collectionID,
|
||||
})
|
||||
) {
|
||||
@@ -1118,7 +1116,7 @@ const onRemoveRequest = () => {
|
||||
if (folderPath === null || requestIndex === null) return
|
||||
|
||||
if (
|
||||
isSelected.value({
|
||||
isSelected({
|
||||
folderPath,
|
||||
requestIndex,
|
||||
})
|
||||
@@ -1136,7 +1134,7 @@ const onRemoveRequest = () => {
|
||||
if (!requestID) return
|
||||
|
||||
if (
|
||||
isSelected.value({
|
||||
isSelected({
|
||||
requestID,
|
||||
})
|
||||
) {
|
||||
@@ -1342,12 +1340,10 @@ const discardRequestChange = () => {
|
||||
* @param path The path of the request
|
||||
* @returns The index of the request
|
||||
*/
|
||||
const pathToIndex = computed(() => {
|
||||
return (path: string) => {
|
||||
const pathArr = path.split("/")
|
||||
return parseInt(pathArr[pathArr.length - 1])
|
||||
}
|
||||
})
|
||||
const pathToLastIndex = (path: string) => {
|
||||
const pathArr = path.split("/")
|
||||
return parseInt(pathArr[pathArr.length - 1])
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when the user drops the request inside a collection
|
||||
@@ -1363,7 +1359,7 @@ const dropRequest = (payload: {
|
||||
if (collectionsType.value.type === "my-collections" && folderPath) {
|
||||
moveRESTRequest(
|
||||
folderPath,
|
||||
pathToIndex.value(requestIndex),
|
||||
pathToLastIndex(requestIndex),
|
||||
destinationCollectionIndex
|
||||
)
|
||||
toast.success(`${t("request.moved")}`)
|
||||
@@ -1395,6 +1391,43 @@ const dropRequest = (payload: {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path The path of the collection or request
|
||||
* @returns The index of the collection or request
|
||||
*/
|
||||
const pathToIndex = (path: string) => {
|
||||
const pathArr = path.split("/")
|
||||
return pathArr
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to check if the collection exist as the parent of the childrens
|
||||
* @param collectionIndexDragged The index of the collection dragged
|
||||
* @param destinationCollectionIndex The index of the destination collection
|
||||
* @returns True if the collection exist as the parent of the childrens
|
||||
*/
|
||||
const checkIfCollectionIsAParentOfTheChildren = (
|
||||
collectionIndexDragged: string,
|
||||
destinationCollectionIndex: string
|
||||
) => {
|
||||
const collectionDraggedPath = pathToIndex(collectionIndexDragged)
|
||||
const destinationCollectionPath = pathToIndex(destinationCollectionIndex)
|
||||
|
||||
if (collectionDraggedPath.length < destinationCollectionPath.length) {
|
||||
const slicedDestinationCollectionPath = destinationCollectionPath.slice(
|
||||
0,
|
||||
collectionDraggedPath.length
|
||||
)
|
||||
if (isEqual(slicedDestinationCollectionPath, collectionDraggedPath)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when the user moves the collection
|
||||
* to a different collection or folder
|
||||
@@ -1408,6 +1441,15 @@ const dropCollection = (payload: {
|
||||
if (!collectionIndexDragged || !destinationCollectionIndex) return
|
||||
if (collectionIndexDragged === destinationCollectionIndex) return
|
||||
if (collectionsType.value.type === "my-collections") {
|
||||
if (
|
||||
checkIfCollectionIsAParentOfTheChildren(
|
||||
collectionIndexDragged,
|
||||
destinationCollectionIndex
|
||||
)
|
||||
) {
|
||||
toast.error(`${t("team.parent_coll_move")}`)
|
||||
return
|
||||
}
|
||||
moveRESTFolder(collectionIndexDragged, destinationCollectionIndex)
|
||||
draggingToRoot.value = false
|
||||
toast.success(`${t("collection.moved")}`)
|
||||
@@ -1445,12 +1487,10 @@ const dropCollection = (payload: {
|
||||
* @param id - path of the collection
|
||||
* @returns boolean - true if the collection is already in the root
|
||||
*/
|
||||
const isAlreadyInRoot = computed(() => {
|
||||
return (id: string) => {
|
||||
const indexPath = id.split("/").map((i) => parseInt(i))
|
||||
return indexPath.length === 1
|
||||
}
|
||||
})
|
||||
const isAlreadyInRoot = (id: string) => {
|
||||
const indexPath = pathToIndex(id)
|
||||
return indexPath.length === 1
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when the user drops the collection
|
||||
@@ -1463,7 +1503,7 @@ const dropToRoot = ({ dataTransfer }: DragEvent) => {
|
||||
if (!collectionIndexDragged) return
|
||||
if (collectionsType.value.type === "my-collections") {
|
||||
// check if the collection is already in the root
|
||||
if (isAlreadyInRoot.value(collectionIndexDragged)) {
|
||||
if (isAlreadyInRoot(collectionIndexDragged)) {
|
||||
toast.error(`${t("collection.invalid_root_move")}`)
|
||||
} else {
|
||||
moveRESTFolder(collectionIndexDragged, null)
|
||||
@@ -1506,26 +1546,25 @@ const dropToRoot = ({ dataTransfer }: DragEvent) => {
|
||||
* @param destinationReq - path index of the destination request
|
||||
* @returns boolean - true if the request is being moved to the same parent
|
||||
*/
|
||||
const isSameSameParent = computed(
|
||||
() => (draggedReq: string, destinationReq: string) => {
|
||||
const draggedReqIndex = draggedReq.split("/").map((i) => parseInt(i))
|
||||
const destinationReqIndex = destinationReq
|
||||
.split("/")
|
||||
.map((i) => parseInt(i))
|
||||
const isSameSameParent = (draggedItem: string, destinationItem: string) => {
|
||||
const draggedItemIndex = pathToIndex(draggedItem)
|
||||
const destinationItemIndex = pathToIndex(destinationItem)
|
||||
|
||||
// length of 1 means the request is in the root
|
||||
if (draggedReqIndex.length === 1 && destinationReqIndex.length === 1) {
|
||||
return true
|
||||
} else if (
|
||||
draggedReqIndex[draggedReqIndex.length - 2] ===
|
||||
destinationReqIndex[destinationReqIndex.length - 2]
|
||||
) {
|
||||
// length of 1 means the request is in the root
|
||||
if (draggedItemIndex.length === 1 && destinationItemIndex.length === 1) {
|
||||
return true
|
||||
} else if (draggedItemIndex.length === destinationItemIndex.length) {
|
||||
const dragedItemParent = draggedItemIndex.slice(0, -1)
|
||||
const destinationItemParent = destinationItemIndex.slice(0, -1)
|
||||
if (isEqual(dragedItemParent, destinationItemParent)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when the user updates the request order in a collection
|
||||
@@ -1553,12 +1592,12 @@ const updateRequestOrder = (payload: {
|
||||
if (dragedRequestIndex === destinationRequestIndex) return
|
||||
|
||||
if (collectionsType.value.type === "my-collections") {
|
||||
if (!isSameSameParent.value(dragedRequestIndex, destinationRequestIndex)) {
|
||||
if (!isSameSameParent(dragedRequestIndex, destinationRequestIndex)) {
|
||||
toast.error(`${t("collection.different_parent")}`)
|
||||
} else {
|
||||
updateRESTRequestOrder(
|
||||
pathToIndex.value(dragedRequestIndex),
|
||||
pathToIndex.value(destinationRequestIndex),
|
||||
pathToLastIndex(dragedRequestIndex),
|
||||
pathToLastIndex(destinationRequestIndex),
|
||||
destinationCollectionIndex
|
||||
)
|
||||
toast.success(`${t("request.order_changed")}`)
|
||||
@@ -1608,9 +1647,7 @@ const updateCollectionOrder = (payload: {
|
||||
if (dragedCollectionIndex === destinationCollectionIndex) return
|
||||
|
||||
if (collectionsType.value.type === "my-collections") {
|
||||
if (
|
||||
!isSameSameParent.value(dragedCollectionIndex, destinationCollectionIndex)
|
||||
) {
|
||||
if (!isSameSameParent(dragedCollectionIndex, destinationCollectionIndex)) {
|
||||
toast.error(`${t("collection.different_parent")}`)
|
||||
} else {
|
||||
updateRESTCollectionOrder(
|
||||
|
||||
@@ -547,6 +547,15 @@ export default class NewTeamCollectionAdapter {
|
||||
)
|
||||
}
|
||||
|
||||
private reorderItems = (array: unknown[], from: number, to: number) => {
|
||||
const item = array.splice(from, 1)[0]
|
||||
if (from < to) {
|
||||
array.splice(to - 1, 0, item)
|
||||
} else {
|
||||
array.splice(to, 0, item)
|
||||
}
|
||||
}
|
||||
|
||||
public updateRequestOrder(
|
||||
dragedRequestID: string,
|
||||
destinationRequestID: string,
|
||||
@@ -570,10 +579,7 @@ export default class NewTeamCollectionAdapter {
|
||||
|
||||
if (requestIndex === -1) return
|
||||
|
||||
const request = collection.requests[requestIndex]
|
||||
|
||||
collection.requests.splice(requestIndex, 1)
|
||||
collection.requests.splice(destinationIndex, 0, request)
|
||||
this.reorderItems(collection.requests, requestIndex, destinationIndex)
|
||||
|
||||
this.collections$.next(tree)
|
||||
}
|
||||
@@ -600,10 +606,7 @@ export default class NewTeamCollectionAdapter {
|
||||
// If the collection index is not found, don't update
|
||||
if (collectionIndex === -1) return
|
||||
|
||||
const collection = coll.children[collectionIndex]
|
||||
|
||||
coll.children.splice(collectionIndex, 1)
|
||||
coll.children.splice(destinationIndex, 0, collection)
|
||||
this.reorderItems(coll.children, collectionIndex, destinationIndex)
|
||||
} else {
|
||||
// If the collection has no parent collection, it is a root collection
|
||||
const collectionIndex = tree.findIndex((coll) => coll.id === collectionID)
|
||||
@@ -615,10 +618,7 @@ export default class NewTeamCollectionAdapter {
|
||||
// If the collection index is not found, don't update
|
||||
if (collectionIndex === -1) return
|
||||
|
||||
const collection = tree[collectionIndex]
|
||||
|
||||
tree.splice(collectionIndex, 1)
|
||||
tree.splice(destinationIndex, 0, collection)
|
||||
this.reorderItems(tree, collectionIndex, destinationIndex)
|
||||
}
|
||||
|
||||
this.collections$.next(tree)
|
||||
|
||||
@@ -31,7 +31,7 @@ const defaultGraphqlCollectionState = {
|
||||
type RESTCollectionStoreType = typeof defaultRESTCollectionState
|
||||
type GraphqlCollectionStoreType = typeof defaultGraphqlCollectionState
|
||||
|
||||
function navigateToFolderWithIndexPath(
|
||||
export function navigateToFolderWithIndexPath(
|
||||
collections: HoppCollection<HoppRESTRequest | HoppGQLRequest>[],
|
||||
indexPaths: number[]
|
||||
) {
|
||||
@@ -45,6 +45,15 @@ function navigateToFolderWithIndexPath(
|
||||
return target !== undefined ? target : null
|
||||
}
|
||||
|
||||
function reorderItems(array: unknown[], from: number, to: number) {
|
||||
const item = array.splice(from, 1)[0]
|
||||
if (from < to) {
|
||||
array.splice(to - 1, 0, item)
|
||||
} else {
|
||||
array.splice(to, 0, item)
|
||||
}
|
||||
}
|
||||
|
||||
const restCollectionDispatchers = defineDispatchers({
|
||||
setCollections(
|
||||
_: RESTCollectionStoreType,
|
||||
@@ -88,12 +97,15 @@ const restCollectionDispatchers = defineDispatchers({
|
||||
{ state }: RESTCollectionStoreType,
|
||||
{
|
||||
collectionIndex,
|
||||
collection,
|
||||
}: { collectionIndex: number; collection: HoppCollection<any> }
|
||||
partialCollection,
|
||||
}: {
|
||||
collectionIndex: number
|
||||
partialCollection: Partial<HoppCollection<any>>
|
||||
}
|
||||
) {
|
||||
return {
|
||||
state: state.map((col, index) =>
|
||||
index === collectionIndex ? collection : col
|
||||
index === collectionIndex ? { ...col, ...partialCollection } : col
|
||||
),
|
||||
}
|
||||
},
|
||||
@@ -295,18 +307,14 @@ const restCollectionDispatchers = defineDispatchers({
|
||||
)
|
||||
|
||||
if (containingFolder === null) {
|
||||
const [removed] = newState.splice(folderIndex, 1)
|
||||
|
||||
newState.splice(destinationFolderIndex, 0, removed)
|
||||
reorderItems(newState, folderIndex, destinationFolderIndex)
|
||||
|
||||
return {
|
||||
state: newState,
|
||||
}
|
||||
}
|
||||
|
||||
const [removed] = containingFolder.folders.splice(folderIndex, 1)
|
||||
|
||||
containingFolder.folders.splice(destinationFolderIndex, 0, removed)
|
||||
reorderItems(containingFolder.folders, folderIndex, destinationFolderIndex)
|
||||
|
||||
return {
|
||||
state: newState,
|
||||
@@ -480,9 +488,7 @@ const restCollectionDispatchers = defineDispatchers({
|
||||
return {}
|
||||
}
|
||||
|
||||
const [removed] = targetLocation.requests.splice(requestIndex, 1)
|
||||
|
||||
targetLocation.requests.splice(destinationRequestIndex, 0, removed)
|
||||
reorderItems(targetLocation.requests, requestIndex, destinationRequestIndex)
|
||||
|
||||
return {
|
||||
state: newState,
|
||||
@@ -821,13 +827,13 @@ export function getRESTCollection(collectionIndex: number) {
|
||||
|
||||
export function editRESTCollection(
|
||||
collectionIndex: number,
|
||||
collection: HoppCollection<HoppRESTRequest>
|
||||
partialCollection: Partial<HoppCollection<HoppRESTRequest>>
|
||||
) {
|
||||
restCollectionStore.dispatch({
|
||||
dispatcher: "editCollection",
|
||||
payload: {
|
||||
collectionIndex,
|
||||
collection,
|
||||
partialCollection: partialCollection,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
46
packages/hoppscotch-common/src/newstore/reordering.ts
Normal file
46
packages/hoppscotch-common/src/newstore/reordering.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { distinctUntilChanged, pluck } from "rxjs"
|
||||
import DispatchingStore, { defineDispatchers } from "./DispatchingStore"
|
||||
|
||||
type ReorderingItem =
|
||||
| { type: "collection"; id: string; parentID: string | null }
|
||||
| { type: "request"; id: string; parentID: string | null }
|
||||
|
||||
type CurrentReorderingState = {
|
||||
currentReorderingItem: ReorderingItem
|
||||
}
|
||||
|
||||
const initialState: CurrentReorderingState = {
|
||||
currentReorderingItem: {
|
||||
type: "collection",
|
||||
id: "",
|
||||
parentID: "",
|
||||
},
|
||||
}
|
||||
|
||||
const dispatchers = defineDispatchers({
|
||||
changeCurrentReorderStatus(
|
||||
_,
|
||||
{ reorderItem }: { reorderItem: ReorderingItem }
|
||||
) {
|
||||
return {
|
||||
currentReorderingItem: reorderItem,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
export const currentReorderStore = new DispatchingStore(
|
||||
initialState,
|
||||
dispatchers
|
||||
)
|
||||
|
||||
export const currentReorderingStatus$ = currentReorderStore.subject$.pipe(
|
||||
pluck("currentReorderingItem"),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
|
||||
export function changeCurrentReorderStatus(reorderItem: ReorderingItem) {
|
||||
currentReorderStore.dispatch({
|
||||
dispatcher: "changeCurrentReorderStatus",
|
||||
payload: { reorderItem },
|
||||
})
|
||||
}
|
||||
52
pnpm-lock.yaml
generated
52
pnpm-lock.yaml
generated
@@ -84,6 +84,7 @@ importers:
|
||||
eslint-config-prettier: ^8.5.0
|
||||
eslint-plugin-prettier: ^4.2.1
|
||||
express: ^4.17.1
|
||||
express-session: ^1.17.3
|
||||
fp-ts: ^2.13.1
|
||||
graphql: ^15.5.0
|
||||
graphql-query-complexity: ^0.12.0
|
||||
@@ -130,6 +131,7 @@ importers:
|
||||
cookie: 0.5.0
|
||||
cookie-parser: 1.4.6
|
||||
express: 4.18.2
|
||||
express-session: 1.17.3
|
||||
fp-ts: 2.13.1
|
||||
graphql: 15.8.0
|
||||
graphql-query-complexity: 0.12.0_graphql@15.8.0
|
||||
@@ -296,6 +298,7 @@ importers:
|
||||
axios: ^0.21.4
|
||||
buffer: ^6.0.3
|
||||
cross-env: ^7.0.3
|
||||
dotenv: ^16.0.3
|
||||
eslint: ^8.24.0
|
||||
eslint-plugin-prettier: ^4.2.1
|
||||
eslint-plugin-vue: ^9.5.1
|
||||
@@ -471,6 +474,7 @@ importers:
|
||||
'@vue/eslint-config-typescript': 11.0.1_kpxf5iryryrlim2ejhkirkiuey
|
||||
'@vue/runtime-core': 3.2.39
|
||||
cross-env: 7.0.3
|
||||
dotenv: 16.0.3
|
||||
eslint: 8.24.0
|
||||
eslint-plugin-prettier: 4.2.1_eslint@8.24.0
|
||||
eslint-plugin-vue: 9.5.1_eslint@8.24.0
|
||||
@@ -4647,7 +4651,7 @@ packages:
|
||||
'@types/jsonwebtoken': 8.5.9
|
||||
chalk: 4.1.2
|
||||
debug: 4.3.4
|
||||
dotenv: 16.0.1
|
||||
dotenv: 16.0.3
|
||||
graphql: 15.8.0
|
||||
graphql-request: 4.3.0_graphql@15.8.0
|
||||
http-proxy-agent: 5.0.0
|
||||
@@ -4681,7 +4685,7 @@ packages:
|
||||
'@types/jsonwebtoken': 9.0.1
|
||||
chalk: 4.1.2
|
||||
debug: 4.3.4
|
||||
dotenv: 16.0.1
|
||||
dotenv: 16.0.3
|
||||
graphql: 16.6.0
|
||||
graphql-request: 5.1.0_graphql@16.6.0
|
||||
http-proxy-agent: 5.0.0
|
||||
@@ -10063,13 +10067,18 @@ packages:
|
||||
dev: false
|
||||
|
||||
/cookie-signature/1.0.6:
|
||||
resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==}
|
||||
resolution: {integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw=}
|
||||
|
||||
/cookie/0.4.1:
|
||||
resolution: {integrity: sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/cookie/0.4.2:
|
||||
resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/cookie/0.5.0:
|
||||
resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@@ -10603,8 +10612,8 @@ packages:
|
||||
is-obj: 2.0.0
|
||||
dev: true
|
||||
|
||||
/dotenv/16.0.1:
|
||||
resolution: {integrity: sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==}
|
||||
/dotenv/16.0.3:
|
||||
resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==}
|
||||
engines: {node: '>=12'}
|
||||
dev: true
|
||||
|
||||
@@ -12062,6 +12071,22 @@ packages:
|
||||
raw-body: 2.5.1
|
||||
dev: false
|
||||
|
||||
/express-session/1.17.3:
|
||||
resolution: {integrity: sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
dependencies:
|
||||
cookie: 0.4.2
|
||||
cookie-signature: 1.0.6
|
||||
debug: 2.6.9
|
||||
depd: 2.0.0
|
||||
on-headers: 1.0.2
|
||||
parseurl: 1.3.3
|
||||
safe-buffer: 5.2.1
|
||||
uid-safe: 2.1.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/express/4.18.2:
|
||||
resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==}
|
||||
engines: {node: '>= 0.10.0'}
|
||||
@@ -16028,6 +16053,11 @@ packages:
|
||||
dependencies:
|
||||
ee-first: 1.1.1
|
||||
|
||||
/on-headers/1.0.2:
|
||||
resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dev: false
|
||||
|
||||
/once/1.4.0:
|
||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||
dependencies:
|
||||
@@ -16844,6 +16874,11 @@ packages:
|
||||
resolution: {integrity: sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==}
|
||||
dev: false
|
||||
|
||||
/random-bytes/1.0.0:
|
||||
resolution: {integrity: sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dev: false
|
||||
|
||||
/randombytes/2.1.0:
|
||||
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
|
||||
dependencies:
|
||||
@@ -18834,6 +18869,13 @@ packages:
|
||||
resolution: {integrity: sha512-boAm74ubXHY7KJQZLlXrtMz52qFvpsbOxDcZOnw/Wf+LS4Mmyu7JxmzD4tDLtUQtmZECypJ0FrCz4QIe6dvKRA==}
|
||||
dev: true
|
||||
|
||||
/uid-safe/2.1.5:
|
||||
resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dependencies:
|
||||
random-bytes: 1.0.0
|
||||
dev: false
|
||||
|
||||
/uid2/0.0.4:
|
||||
resolution: {integrity: sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==}
|
||||
dev: false
|
||||
|
||||
Reference in New Issue
Block a user