mirror of
https://github.com/hoppscotch/hoppscotch
synced 2024-11-23 07:39:55 +00:00
441 lines
9.6 KiB
TypeScript
441 lines
9.6 KiB
TypeScript
import { pluck, distinctUntilChanged, map } from "rxjs/operators"
|
|
import DispatchingStore, { defineDispatchers } from "./DispatchingStore"
|
|
import {
|
|
HoppRESTHeader,
|
|
HoppRESTParam,
|
|
HoppRESTRequest,
|
|
} from "~/helpers/types/HoppRESTRequest"
|
|
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
|
|
|
function getParamsInURL(url: string): { key: string; value: string }[] {
|
|
const result: { key: string; value: string }[] = []
|
|
|
|
try {
|
|
const uriObj = new URL(url)
|
|
|
|
uriObj.searchParams.forEach((value, key) => {
|
|
result.push({ key, value })
|
|
})
|
|
} catch (_e) {}
|
|
|
|
return result
|
|
}
|
|
|
|
function recalculateParams(
|
|
oldURL: string,
|
|
currentParams: HoppRESTParam[],
|
|
newParams: { key: string; value: string }[]
|
|
): HoppRESTParam[] {
|
|
const paramsInOldURL = getParamsInURL(oldURL).map((x) => x.key)
|
|
|
|
const checkingParams = currentParams.filter(
|
|
(x) => !paramsInOldURL.includes(x.key)
|
|
)
|
|
|
|
const result: HoppRESTParam[] = []
|
|
|
|
const addedKeys: string[] = []
|
|
|
|
newParams.forEach(({ key, value }) => {
|
|
const currentParam = checkingParams.find(
|
|
({ key: currentKey }) => currentKey === key
|
|
)
|
|
|
|
if (!currentParam) {
|
|
addedKeys.push(key)
|
|
result.push({ key, value, active: true })
|
|
} else {
|
|
addedKeys.push(key)
|
|
result.push({ key, value, active: currentParam.active })
|
|
}
|
|
})
|
|
|
|
result.push(...checkingParams.filter((x) => !addedKeys.includes(x.key)))
|
|
|
|
return result
|
|
}
|
|
|
|
function removeParamFromURL(url: string, param: string): string {
|
|
try {
|
|
const urlObj = new URL(url)
|
|
urlObj.searchParams.delete(param)
|
|
return urlObj.toString()
|
|
} catch (e) {
|
|
return url
|
|
}
|
|
}
|
|
|
|
function removeAllParamsFromURL(url: string): string {
|
|
try {
|
|
const urlObj = new URL(url)
|
|
const params: string[] = []
|
|
|
|
urlObj.searchParams.forEach((_value, key) => params.push(key))
|
|
|
|
params.forEach((key) => urlObj.searchParams.delete(key))
|
|
|
|
return urlObj.toString()
|
|
} catch (e) {
|
|
return url
|
|
}
|
|
}
|
|
|
|
function updateURLParam(
|
|
url: string,
|
|
currKey: string,
|
|
newKey: string,
|
|
newValue: string
|
|
): string {
|
|
try {
|
|
const urlObj = new URL(url)
|
|
|
|
let params: { key: string; value: string }[] = []
|
|
|
|
urlObj.searchParams.forEach((value, key) => params.push({ key, value }))
|
|
|
|
params.forEach((x) => urlObj.searchParams.delete(x.key))
|
|
|
|
params = params.map((x) => {
|
|
if (x.key === currKey) return { key: newKey, value: newValue }
|
|
else return x
|
|
})
|
|
|
|
params.forEach((x) => urlObj.searchParams.append(x.key, x.value))
|
|
|
|
return urlObj.toString()
|
|
} catch (e) {
|
|
return url
|
|
}
|
|
}
|
|
|
|
type RESTSession = {
|
|
request: HoppRESTRequest
|
|
response: HoppRESTResponse | null
|
|
}
|
|
|
|
const defaultRESTSession: RESTSession = {
|
|
request: {
|
|
endpoint: "https://httpbin.org/",
|
|
params: [],
|
|
headers: [],
|
|
method: "GET",
|
|
},
|
|
response: null,
|
|
}
|
|
|
|
const dispatchers = defineDispatchers({
|
|
setEndpoint(curr: RESTSession, { newEndpoint }: { newEndpoint: string }) {
|
|
const paramsInNewURL = getParamsInURL(newEndpoint)
|
|
const updatedParams = recalculateParams(
|
|
curr.request.endpoint,
|
|
curr.request.params,
|
|
paramsInNewURL
|
|
)
|
|
|
|
return {
|
|
request: {
|
|
...curr.request,
|
|
endpoint: newEndpoint,
|
|
params: updatedParams,
|
|
},
|
|
}
|
|
},
|
|
addParam(curr: RESTSession, { newParam }: { newParam: HoppRESTParam }) {
|
|
return {
|
|
request: {
|
|
...curr.request,
|
|
params: [...curr.request.params, newParam],
|
|
},
|
|
}
|
|
},
|
|
updateParam(
|
|
curr: RESTSession,
|
|
{ index, updatedParam }: { index: number; updatedParam: HoppRESTParam }
|
|
) {
|
|
const paramsInURL = getParamsInURL(curr.request.endpoint).map((x) => x.key)
|
|
|
|
if (paramsInURL.includes(curr.request.params[index].key)) {
|
|
const updatedURL = updateURLParam(
|
|
curr.request.endpoint,
|
|
curr.request.params[index].key,
|
|
updatedParam.key,
|
|
updatedParam.value
|
|
)
|
|
|
|
const newParams = curr.request.params.map((param, i) => {
|
|
if (i === index) return updatedParam
|
|
else return param
|
|
})
|
|
|
|
return {
|
|
request: {
|
|
...curr.request,
|
|
endpoint: updatedURL,
|
|
params: newParams,
|
|
},
|
|
}
|
|
} else {
|
|
const newParams = curr.request.params.map((param, i) => {
|
|
if (i === index) return updatedParam
|
|
else return param
|
|
})
|
|
|
|
return {
|
|
request: {
|
|
...curr.request,
|
|
params: newParams,
|
|
},
|
|
}
|
|
}
|
|
},
|
|
deleteParam(curr: RESTSession, { index }: { index: number }) {
|
|
const paramsFromURL = getParamsInURL(curr.request.endpoint).map(
|
|
(x) => x.key
|
|
)
|
|
if (paramsFromURL.includes(curr.request.params[index].key)) {
|
|
const newURL = removeParamFromURL(
|
|
curr.request.endpoint,
|
|
curr.request.params[index].key
|
|
)
|
|
|
|
const newParams = getParamsInURL(newURL)
|
|
|
|
const recalculatedParams = recalculateParams(
|
|
curr.request.endpoint,
|
|
curr.request.params,
|
|
newParams
|
|
)
|
|
return {
|
|
request: {
|
|
...curr.request,
|
|
endpoint: newURL,
|
|
params: recalculatedParams,
|
|
},
|
|
}
|
|
} else {
|
|
const newParams = curr.request.params.filter((_x, i) => i !== index)
|
|
|
|
return {
|
|
request: {
|
|
...curr.request,
|
|
params: newParams,
|
|
},
|
|
}
|
|
}
|
|
},
|
|
deleteAllParams(curr: RESTSession) {
|
|
const newURL = removeAllParamsFromURL(curr.request.endpoint)
|
|
|
|
return {
|
|
request: {
|
|
...curr.request,
|
|
endpoint: newURL,
|
|
params: [],
|
|
},
|
|
}
|
|
},
|
|
updateMethod(curr: RESTSession, { newMethod }: { newMethod: string }) {
|
|
return {
|
|
request: {
|
|
...curr.request,
|
|
method: newMethod,
|
|
},
|
|
}
|
|
},
|
|
addHeader(curr: RESTSession, { entry }: { entry: HoppRESTHeader }) {
|
|
return {
|
|
request: {
|
|
...curr.request,
|
|
headers: [...curr.request.headers, entry],
|
|
},
|
|
}
|
|
},
|
|
updateHeader(
|
|
curr: RESTSession,
|
|
{ index, updatedEntry }: { index: number; updatedEntry: HoppRESTHeader }
|
|
) {
|
|
return {
|
|
request: {
|
|
...curr.request,
|
|
headers: curr.request.headers.map((header, i) => {
|
|
if (i === index) return updatedEntry
|
|
else return header
|
|
}),
|
|
},
|
|
}
|
|
},
|
|
deleteHeader(curr: RESTSession, { index }: { index: number }) {
|
|
return {
|
|
request: {
|
|
...curr.request,
|
|
headers: curr.request.headers.filter((_, i) => i !== index),
|
|
},
|
|
}
|
|
},
|
|
deleteAllHeaders(curr: RESTSession) {
|
|
return {
|
|
request: {
|
|
...curr.request,
|
|
headers: [],
|
|
},
|
|
}
|
|
},
|
|
updateResponse(
|
|
_curr: RESTSession,
|
|
{ updatedRes }: { updatedRes: HoppRESTResponse | null }
|
|
) {
|
|
return {
|
|
response: updatedRes,
|
|
}
|
|
},
|
|
clearResponse(_curr: RESTSession) {
|
|
return {
|
|
response: null,
|
|
}
|
|
},
|
|
})
|
|
|
|
const restSessionStore = new DispatchingStore(defaultRESTSession, dispatchers)
|
|
|
|
export function setRESTEndpoint(newEndpoint: string) {
|
|
restSessionStore.dispatch({
|
|
dispatcher: "setEndpoint",
|
|
payload: {
|
|
newEndpoint,
|
|
},
|
|
})
|
|
}
|
|
|
|
export function addRESTParam(newParam: HoppRESTParam) {
|
|
restSessionStore.dispatch({
|
|
dispatcher: "addParam",
|
|
payload: {
|
|
newParam,
|
|
},
|
|
})
|
|
}
|
|
|
|
export function updateRESTParam(index: number, updatedParam: HoppRESTParam) {
|
|
restSessionStore.dispatch({
|
|
dispatcher: "updateParam",
|
|
payload: {
|
|
updatedParam,
|
|
index,
|
|
},
|
|
})
|
|
}
|
|
|
|
export function deleteRESTParam(index: number) {
|
|
restSessionStore.dispatch({
|
|
dispatcher: "deleteParam",
|
|
payload: {
|
|
index,
|
|
},
|
|
})
|
|
}
|
|
|
|
export function deleteAllRESTParams() {
|
|
restSessionStore.dispatch({
|
|
dispatcher: "deleteAllParams",
|
|
payload: {},
|
|
})
|
|
}
|
|
|
|
export function updateRESTMethod(newMethod: string) {
|
|
restSessionStore.dispatch({
|
|
dispatcher: "updateMethod",
|
|
payload: {
|
|
newMethod,
|
|
},
|
|
})
|
|
}
|
|
|
|
export function addRESTHeader(entry: HoppRESTHeader) {
|
|
restSessionStore.dispatch({
|
|
dispatcher: "addHeader",
|
|
payload: {
|
|
entry,
|
|
},
|
|
})
|
|
}
|
|
|
|
export function updateRESTHeader(index: number, updatedEntry: HoppRESTHeader) {
|
|
restSessionStore.dispatch({
|
|
dispatcher: "updateHeader",
|
|
payload: {
|
|
index,
|
|
updatedEntry,
|
|
},
|
|
})
|
|
}
|
|
|
|
export function deleteRESTHeader(index: number) {
|
|
restSessionStore.dispatch({
|
|
dispatcher: "deleteHeader",
|
|
payload: {
|
|
index,
|
|
},
|
|
})
|
|
}
|
|
|
|
export function deleteAllRESTHeaders() {
|
|
restSessionStore.dispatch({
|
|
dispatcher: "deleteAllHeaders",
|
|
payload: {},
|
|
})
|
|
}
|
|
|
|
export function updateRESTResponse(updatedRes: HoppRESTResponse | null) {
|
|
restSessionStore.dispatch({
|
|
dispatcher: "updateResponse",
|
|
payload: {
|
|
updatedRes,
|
|
},
|
|
})
|
|
}
|
|
|
|
export function clearRESTResponse() {
|
|
restSessionStore.dispatch({
|
|
dispatcher: "clearResponse",
|
|
payload: {},
|
|
})
|
|
}
|
|
|
|
export const restRequest$ = restSessionStore.subject$.pipe(
|
|
pluck("request"),
|
|
distinctUntilChanged()
|
|
)
|
|
|
|
export const restEndpoint$ = restSessionStore.subject$.pipe(
|
|
pluck("request", "endpoint"),
|
|
distinctUntilChanged()
|
|
)
|
|
|
|
export const restParams$ = restSessionStore.subject$.pipe(
|
|
pluck("request", "params"),
|
|
distinctUntilChanged()
|
|
)
|
|
|
|
export const restActiveParamsCount$ = restParams$.pipe(
|
|
map((params) => params.filter((x) => x.active).length)
|
|
)
|
|
|
|
export const restMethod$ = restSessionStore.subject$.pipe(
|
|
pluck("request", "method"),
|
|
distinctUntilChanged()
|
|
)
|
|
|
|
export const restHeaders$ = restSessionStore.subject$.pipe(
|
|
pluck("request", "headers"),
|
|
distinctUntilChanged()
|
|
)
|
|
|
|
export const restActiveHeadersCount$ = restHeaders$.pipe(
|
|
map((params) => params.filter((x) => x.active).length)
|
|
)
|
|
|
|
export const restResponse$ = restSessionStore.subject$.pipe(
|
|
pluck("response"),
|
|
distinctUntilChanged()
|
|
)
|