123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- import eq from "lodash/eq"
- import { pluck } from "rxjs/operators"
- import {
- HoppRESTRequest,
- translateToNewRequest,
- HoppGQLRequest,
- translateToGQLRequest,
- GQL_REQ_SCHEMA_VERSION,
- } from "@hoppscotch/data"
- import DispatchingStore, { defineDispatchers } from "./DispatchingStore"
- import { completedRESTResponse$ } from "./RESTSession"
- export type RESTHistoryEntry = {
- v: number
- request: HoppRESTRequest
- responseMeta: {
- duration: number | null
- statusCode: number | null
- }
- star: boolean
- id?: string // For when Firebase Firestore is set
- updatedOn?: Date
- }
- export type GQLHistoryEntry = {
- v: number
- request: HoppGQLRequest
- response: string
- star: boolean
- id?: string // For when Firestore ID is set
- updatedOn?: Date
- }
- export function makeRESTHistoryEntry(
- x: Omit<RESTHistoryEntry, "v">
- ): RESTHistoryEntry {
- return {
- v: 1,
- ...x,
- }
- }
- export function makeGQLHistoryEntry(
- x: Omit<GQLHistoryEntry, "v">
- ): GQLHistoryEntry {
- return {
- v: 1,
- ...x,
- updatedOn: new Date(),
- }
- }
- export function translateToNewRESTHistory(x: any): RESTHistoryEntry {
- if (x.v === 1) return x
- // Legacy
- const request = translateToNewRequest(x)
- const star = x.star ?? false
- const duration = x.duration ?? null
- const statusCode = x.status ?? null
- const updatedOn = x.updatedOn ?? null
- const obj: RESTHistoryEntry = makeRESTHistoryEntry({
- request,
- star,
- responseMeta: {
- duration,
- statusCode,
- },
- updatedOn,
- })
- if (x.id) obj.id = x.id
- return obj
- }
- export function translateToNewGQLHistory(x: any): GQLHistoryEntry {
- if (x.v === 1 && x.request.v === GQL_REQ_SCHEMA_VERSION) return x
- // Legacy
- const request = x.request
- ? translateToGQLRequest(x.request)
- : translateToGQLRequest(x)
- const star = x.star ?? false
- const response = x.response ?? ""
- const updatedOn = x.updatedOn ?? ""
- const obj: GQLHistoryEntry = makeGQLHistoryEntry({
- request,
- star,
- response,
- updatedOn,
- })
- if (x.id) obj.id = x.id
- return obj
- }
- export const defaultRESTHistoryState = {
- state: [] as RESTHistoryEntry[],
- }
- export const defaultGraphqlHistoryState = {
- state: [] as GQLHistoryEntry[],
- }
- export const HISTORY_LIMIT = 50
- type RESTHistoryType = typeof defaultRESTHistoryState
- type GraphqlHistoryType = typeof defaultGraphqlHistoryState
- const RESTHistoryDispatchers = defineDispatchers({
- setEntries(_: RESTHistoryType, { entries }: { entries: RESTHistoryEntry[] }) {
- return {
- state: entries,
- }
- },
- addEntry(
- currentVal: RESTHistoryType,
- { entry }: { entry: RESTHistoryEntry }
- ) {
- return {
- state: [entry, ...currentVal.state].slice(0, HISTORY_LIMIT),
- }
- },
- deleteEntry(
- currentVal: RESTHistoryType,
- { entry }: { entry: RESTHistoryEntry }
- ) {
- return {
- state: currentVal.state.filter((e) => !eq(e, entry)),
- }
- },
- clearHistory() {
- return {
- state: [],
- }
- },
- toggleStar(
- currentVal: RESTHistoryType,
- { entry }: { entry: RESTHistoryEntry }
- ) {
- return {
- state: currentVal.state.map((e) => {
- if (eq(e, entry) && e.star !== undefined) {
- return {
- ...e,
- star: !e.star,
- }
- }
- return e
- }),
- }
- },
- })
- const GQLHistoryDispatchers = defineDispatchers({
- setEntries(
- _: GraphqlHistoryType,
- { entries }: { entries: GQLHistoryEntry[] }
- ) {
- return {
- state: entries,
- }
- },
- addEntry(
- currentVal: GraphqlHistoryType,
- { entry }: { entry: GQLHistoryEntry }
- ) {
- return {
- state: [entry, ...currentVal.state].slice(0, HISTORY_LIMIT),
- }
- },
- deleteEntry(
- currentVal: GraphqlHistoryType,
- { entry }: { entry: GQLHistoryEntry }
- ) {
- return {
- state: currentVal.state.filter((e) => !eq(e, entry)),
- }
- },
- clearHistory() {
- return {
- state: [],
- }
- },
- toggleStar(
- currentVal: GraphqlHistoryType,
- { entry }: { entry: GQLHistoryEntry }
- ) {
- return {
- state: currentVal.state.map((e) => {
- if (eq(e, entry) && e.star !== undefined) {
- return {
- ...e,
- star: !e.star,
- }
- }
- return e
- }),
- }
- },
- })
- export const restHistoryStore = new DispatchingStore(
- defaultRESTHistoryState,
- RESTHistoryDispatchers
- )
- export const graphqlHistoryStore = new DispatchingStore(
- defaultGraphqlHistoryState,
- GQLHistoryDispatchers
- )
- export const restHistory$ = restHistoryStore.subject$.pipe(pluck("state"))
- export const graphqlHistory$ = graphqlHistoryStore.subject$.pipe(pluck("state"))
- export function setRESTHistoryEntries(entries: RESTHistoryEntry[]) {
- restHistoryStore.dispatch({
- dispatcher: "setEntries",
- payload: { entries },
- })
- }
- export function addRESTHistoryEntry(entry: RESTHistoryEntry) {
- restHistoryStore.dispatch({
- dispatcher: "addEntry",
- payload: { entry },
- })
- }
- export function deleteRESTHistoryEntry(entry: RESTHistoryEntry) {
- restHistoryStore.dispatch({
- dispatcher: "deleteEntry",
- payload: { entry },
- })
- }
- export function clearRESTHistory() {
- restHistoryStore.dispatch({
- dispatcher: "clearHistory",
- payload: {},
- })
- }
- export function toggleRESTHistoryEntryStar(entry: RESTHistoryEntry) {
- restHistoryStore.dispatch({
- dispatcher: "toggleStar",
- payload: { entry },
- })
- }
- export function setGraphqlHistoryEntries(entries: GQLHistoryEntry[]) {
- graphqlHistoryStore.dispatch({
- dispatcher: "setEntries",
- payload: { entries },
- })
- }
- export function addGraphqlHistoryEntry(entry: GQLHistoryEntry) {
- graphqlHistoryStore.dispatch({
- dispatcher: "addEntry",
- payload: { entry },
- })
- }
- export function deleteGraphqlHistoryEntry(entry: GQLHistoryEntry) {
- graphqlHistoryStore.dispatch({
- dispatcher: "deleteEntry",
- payload: { entry },
- })
- }
- export function clearGraphqlHistory() {
- graphqlHistoryStore.dispatch({
- dispatcher: "clearHistory",
- payload: {},
- })
- }
- export function toggleGraphqlHistoryEntryStar(entry: GQLHistoryEntry) {
- graphqlHistoryStore.dispatch({
- dispatcher: "toggleStar",
- payload: { entry },
- })
- }
- // Listen to completed responses to add to history
- completedRESTResponse$.subscribe((res) => {
- if (res !== null) {
- if (
- res.type === "loading" ||
- res.type === "network_fail" ||
- res.type === "script_fail"
- )
- return
- addRESTHistoryEntry(
- makeRESTHistoryEntry({
- request: {
- auth: res.req.auth,
- body: res.req.body,
- endpoint: res.req.endpoint,
- headers: res.req.headers,
- method: res.req.method,
- name: res.req.name,
- params: res.req.params,
- preRequestScript: res.req.preRequestScript,
- testScript: res.req.testScript,
- v: res.req.v,
- },
- responseMeta: {
- duration: res.meta.responseDuration,
- statusCode: res.statusCode,
- },
- star: false,
- updatedOn: new Date(),
- })
- )
- }
- })
|