123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749 |
- import { pluck, distinctUntilChanged, map, filter } from "rxjs/operators"
- import { Ref } from "@nuxtjs/composition-api"
- import DispatchingStore, { defineDispatchers } from "./DispatchingStore"
- import {
- FormDataKeyValue,
- HoppRESTHeader,
- HoppRESTParam,
- HoppRESTReqBody,
- HoppRESTRequest,
- RESTReqSchemaVersion,
- } from "~/helpers/types/HoppRESTRequest"
- import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
- import { useStream } from "~/helpers/utils/composables"
- import { HoppTestResult } from "~/helpers/types/HoppTestResult"
- import { HoppRESTAuth } from "~/helpers/types/HoppRESTAuth"
- import { ValidContentTypes } from "~/helpers/utils/contenttypes"
- import { HoppRequestSaveContext } from "~/helpers/types/HoppRequestSaveContext"
- type RESTSession = {
- request: HoppRESTRequest
- response: HoppRESTResponse | null
- testResults: HoppTestResult | null
- saveContext: HoppRequestSaveContext | null
- }
- export const defaultRESTRequest: HoppRESTRequest = {
- v: RESTReqSchemaVersion,
- endpoint: "https://echo.hoppscotch.io",
- name: "Untitled request",
- params: [{ key: "", value: "", active: true }],
- headers: [{ key: "", value: "", active: true }],
- method: "GET",
- auth: {
- authType: "none",
- authActive: true,
- },
- preRequestScript: "",
- testScript: "",
- body: {
- contentType: null,
- body: null,
- },
- }
- const defaultRESTSession: RESTSession = {
- request: defaultRESTRequest,
- response: null,
- testResults: null,
- saveContext: null,
- }
- const dispatchers = defineDispatchers({
- setRequest(_: RESTSession, { req }: { req: HoppRESTRequest }) {
- return {
- request: req,
- }
- },
- setRequestName(curr: RESTSession, { newName }: { newName: string }) {
- return {
- request: {
- ...curr.request,
- name: newName,
- },
- }
- },
- setEndpoint(curr: RESTSession, { newEndpoint }: { newEndpoint: string }) {
- return {
- request: {
- ...curr.request,
- endpoint: newEndpoint,
- },
- }
- },
- setParams(curr: RESTSession, { entries }: { entries: HoppRESTParam[] }) {
- return {
- request: {
- ...curr.request,
- params: entries,
- },
- }
- },
- 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 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 newParams = curr.request.params.filter((_x, i) => i !== index)
- return {
- request: {
- ...curr.request,
- params: newParams,
- },
- }
- },
- deleteAllParams(curr: RESTSession) {
- return {
- request: {
- ...curr.request,
- params: [],
- },
- }
- },
- updateMethod(curr: RESTSession, { newMethod }: { newMethod: string }) {
- return {
- request: {
- ...curr.request,
- method: newMethod,
- },
- }
- },
- setHeaders(curr: RESTSession, { entries }: { entries: HoppRESTHeader[] }) {
- return {
- request: {
- ...curr.request,
- headers: entries,
- },
- }
- },
- 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: [],
- },
- }
- },
- setAuth(curr: RESTSession, { newAuth }: { newAuth: HoppRESTAuth }) {
- return {
- request: {
- ...curr.request,
- auth: newAuth,
- },
- }
- },
- setPreRequestScript(curr: RESTSession, { newScript }: { newScript: string }) {
- return {
- request: {
- ...curr.request,
- preRequestScript: newScript,
- },
- }
- },
- setTestScript(curr: RESTSession, { newScript }: { newScript: string }) {
- return {
- request: {
- ...curr.request,
- testScript: newScript,
- },
- }
- },
- setContentType(
- curr: RESTSession,
- { newContentType }: { newContentType: ValidContentTypes | null }
- ) {
- // TODO: persist body evenafter switching content typees
- if (curr.request.body.contentType !== "multipart/form-data") {
- if (newContentType === "multipart/form-data") {
- // Going from non-formdata to form-data, discard contents and set empty array as body
- return {
- request: {
- ...curr.request,
- body: <HoppRESTReqBody>{
- contentType: "multipart/form-data",
- body: [],
- },
- },
- }
- } else {
- // non-formdata to non-formdata, keep body and set content type
- return {
- request: {
- ...curr.request,
- body: <HoppRESTReqBody>{
- contentType: newContentType,
- body:
- newContentType === null
- ? null
- : (curr.request.body as any)?.body ?? "",
- },
- },
- }
- }
- } else if (newContentType !== "multipart/form-data") {
- // Going from formdata to non-formdata, discard contents and set empty string
- return {
- request: {
- ...curr.request,
- body: <HoppRESTReqBody>{
- contentType: newContentType,
- body: "",
- },
- },
- }
- } else {
- // form-data to form-data ? just set the content type ¯\_(ツ)_/¯
- return {
- request: {
- ...curr.request,
- body: <HoppRESTReqBody>{
- contentType: newContentType,
- body: curr.request.body.body,
- },
- },
- }
- }
- },
- addFormDataEntry(curr: RESTSession, { entry }: { entry: FormDataKeyValue }) {
- // Only perform update if the current content-type is formdata
- if (curr.request.body.contentType !== "multipart/form-data") return {}
- return {
- request: {
- ...curr.request,
- body: <HoppRESTReqBody>{
- contentType: "multipart/form-data",
- body: [...curr.request.body.body, entry],
- },
- },
- }
- },
- deleteFormDataEntry(curr: RESTSession, { index }: { index: number }) {
- // Only perform update if the current content-type is formdata
- if (curr.request.body.contentType !== "multipart/form-data") return {}
- return {
- request: {
- ...curr.request,
- body: <HoppRESTReqBody>{
- contentType: "multipart/form-data",
- body: curr.request.body.body.filter((_, i) => i !== index),
- },
- },
- }
- },
- updateFormDataEntry(
- curr: RESTSession,
- { index, entry }: { index: number; entry: FormDataKeyValue }
- ) {
- // Only perform update if the current content-type is formdata
- if (curr.request.body.contentType !== "multipart/form-data") return {}
- return {
- request: {
- ...curr.request,
- body: <HoppRESTReqBody>{
- contentType: "multipart/form-data",
- body: curr.request.body.body.map((x, i) => (i !== index ? x : entry)),
- },
- },
- }
- },
- deleteAllFormDataEntries(curr: RESTSession) {
- // Only perform update if the current content-type is formdata
- if (curr.request.body.contentType !== "multipart/form-data") return {}
- return {
- request: {
- ...curr.request,
- body: <HoppRESTReqBody>{
- contentType: "multipart/form-data",
- body: [],
- },
- },
- }
- },
- setRequestBody(curr: RESTSession, { newBody }: { newBody: HoppRESTReqBody }) {
- return {
- request: {
- ...curr.request,
- body: newBody,
- },
- }
- },
- updateResponse(
- _curr: RESTSession,
- { updatedRes }: { updatedRes: HoppRESTResponse | null }
- ) {
- return {
- response: updatedRes,
- }
- },
- clearResponse(_curr: RESTSession) {
- return {
- response: null,
- }
- },
- setTestResults(
- _curr: RESTSession,
- { newResults }: { newResults: HoppTestResult | null }
- ) {
- return {
- testResults: newResults,
- }
- },
- setSaveContext(
- _,
- { newContext }: { newContext: HoppRequestSaveContext | null }
- ) {
- return {
- saveContext: newContext,
- }
- },
- })
- const restSessionStore = new DispatchingStore(defaultRESTSession, dispatchers)
- export function getRESTRequest() {
- return restSessionStore.subject$.value.request
- }
- export function setRESTRequest(
- req: HoppRESTRequest,
- saveContext?: HoppRequestSaveContext | null
- ) {
- restSessionStore.dispatch({
- dispatcher: "setRequest",
- payload: {
- req,
- },
- })
- if (saveContext) setRESTSaveContext(saveContext)
- }
- export function setRESTSaveContext(saveContext: HoppRequestSaveContext | null) {
- restSessionStore.dispatch({
- dispatcher: "setSaveContext",
- payload: {
- newContext: saveContext,
- },
- })
- }
- export function getRESTSaveContext() {
- return restSessionStore.value.saveContext
- }
- export function resetRESTRequest() {
- setRESTRequest(defaultRESTRequest)
- }
- export function setRESTEndpoint(newEndpoint: string) {
- restSessionStore.dispatch({
- dispatcher: "setEndpoint",
- payload: {
- newEndpoint,
- },
- })
- }
- export function setRESTRequestName(newName: string) {
- restSessionStore.dispatch({
- dispatcher: "setRequestName",
- payload: {
- newName,
- },
- })
- }
- export function setRESTParams(entries: HoppRESTParam[]) {
- restSessionStore.dispatch({
- dispatcher: "setParams",
- payload: {
- entries,
- },
- })
- }
- 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 setRESTHeaders(entries: HoppRESTHeader[]) {
- restSessionStore.dispatch({
- dispatcher: "setHeaders",
- payload: {
- entries,
- },
- })
- }
- 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 setRESTAuth(newAuth: HoppRESTAuth) {
- restSessionStore.dispatch({
- dispatcher: "setAuth",
- payload: {
- newAuth,
- },
- })
- }
- export function setRESTPreRequestScript(newScript: string) {
- restSessionStore.dispatch({
- dispatcher: "setPreRequestScript",
- payload: {
- newScript,
- },
- })
- }
- export function setRESTTestScript(newScript: string) {
- restSessionStore.dispatch({
- dispatcher: "setTestScript",
- payload: {
- newScript,
- },
- })
- }
- export function setRESTReqBody(newBody: HoppRESTReqBody | null) {
- restSessionStore.dispatch({
- dispatcher: "setRequestBody",
- payload: {
- newBody,
- },
- })
- }
- export function updateRESTResponse(updatedRes: HoppRESTResponse | null) {
- restSessionStore.dispatch({
- dispatcher: "updateResponse",
- payload: {
- updatedRes,
- },
- })
- }
- export function clearRESTResponse() {
- restSessionStore.dispatch({
- dispatcher: "clearResponse",
- payload: {},
- })
- }
- export function setRESTTestResults(newResults: HoppTestResult | null) {
- restSessionStore.dispatch({
- dispatcher: "setTestResults",
- payload: {
- newResults,
- },
- })
- }
- export function addFormDataEntry(entry: FormDataKeyValue) {
- restSessionStore.dispatch({
- dispatcher: "addFormDataEntry",
- payload: {
- entry,
- },
- })
- }
- export function deleteFormDataEntry(index: number) {
- restSessionStore.dispatch({
- dispatcher: "deleteFormDataEntry",
- payload: {
- index,
- },
- })
- }
- export function updateFormDataEntry(index: number, entry: FormDataKeyValue) {
- restSessionStore.dispatch({
- dispatcher: "updateFormDataEntry",
- payload: {
- index,
- entry,
- },
- })
- }
- export function setRESTContentType(newContentType: ValidContentTypes | null) {
- restSessionStore.dispatch({
- dispatcher: "setContentType",
- payload: {
- newContentType,
- },
- })
- }
- export function deleteAllFormDataEntries() {
- restSessionStore.dispatch({
- dispatcher: "deleteAllFormDataEntries",
- payload: {},
- })
- }
- export const restSaveContext$ = restSessionStore.subject$.pipe(
- pluck("saveContext"),
- distinctUntilChanged()
- )
- export const restRequest$ = restSessionStore.subject$.pipe(
- pluck("request"),
- distinctUntilChanged()
- )
- export const restRequestName$ = restRequest$.pipe(
- pluck("name"),
- 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 && (x.key !== "" || x.value !== "")).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 && (x.key !== "" || x.value !== "")).length
- )
- )
- export const restAuth$ = restRequest$.pipe(pluck("auth"))
- export const restPreRequestScript$ = restSessionStore.subject$.pipe(
- pluck("request", "preRequestScript"),
- distinctUntilChanged()
- )
- export const restContentType$ = restRequest$.pipe(
- pluck("body", "contentType"),
- distinctUntilChanged()
- )
- export const restTestScript$ = restSessionStore.subject$.pipe(
- pluck("request", "testScript"),
- distinctUntilChanged()
- )
- export const restReqBody$ = restSessionStore.subject$.pipe(
- pluck("request", "body"),
- distinctUntilChanged()
- )
- export const restResponse$ = restSessionStore.subject$.pipe(
- pluck("response"),
- distinctUntilChanged()
- )
- export const completedRESTResponse$ = restResponse$.pipe(
- filter(
- (res) =>
- res !== null && res.type !== "loading" && res.type !== "network_fail"
- )
- )
- export const restTestResults$ = restSessionStore.subject$.pipe(
- pluck("testResults"),
- distinctUntilChanged()
- )
- /**
- * A Vue 3 composable function that gives access to a ref
- * which is updated to the preRequestScript value in the store.
- * The ref value is kept in sync with the store and all writes
- * to the ref are dispatched to the store as `setPreRequestScript`
- * dispatches.
- */
- export function usePreRequestScript(): Ref<string> {
- return useStream(
- restPreRequestScript$,
- restSessionStore.value.request.preRequestScript,
- (value) => {
- setRESTPreRequestScript(value)
- }
- )
- }
- /**
- * A Vue 3 composable function that gives access to a ref
- * which is updated to the testScript value in the store.
- * The ref value is kept in sync with the store and all writes
- * to the ref are dispatched to the store as `setTestScript`
- * dispatches.
- */
- export function useTestScript(): Ref<string> {
- return useStream(
- restTestScript$,
- restSessionStore.value.request.testScript,
- (value) => {
- setRESTTestScript(value)
- }
- )
- }
- export function useRESTRequestBody(): Ref<HoppRESTReqBody> {
- return useStream(
- restReqBody$,
- restSessionStore.value.request.body,
- setRESTReqBody
- )
- }
- export function useRESTRequestName(): Ref<string> {
- return useStream(
- restRequestName$,
- restSessionStore.value.request.name,
- setRESTRequestName
- )
- }
|