feat: history migration from legacy request object
This commit is contained in:
@@ -85,7 +85,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from "@nuxtjs/composition-api"
|
import { defineComponent, PropType } from "@nuxtjs/composition-api"
|
||||||
import { useReadonlyStream } from "~/helpers/utils/composables"
|
import { useReadonlyStream } from "~/helpers/utils/composables"
|
||||||
import {
|
import {
|
||||||
restHistory$,
|
restHistory$,
|
||||||
@@ -101,7 +101,7 @@ import { setRESTRequest } from "~/newstore/RESTSession"
|
|||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
page: { type: String, default: null },
|
page: { type: String as PropType<"rest" | "graphql">, default: null },
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
:title="duration"
|
:title="duration"
|
||||||
@click="$emit('use-entry')"
|
@click="$emit('use-entry')"
|
||||||
>
|
>
|
||||||
{{ entry.method }}
|
{{ entry.request.method }}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="
|
class="
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
@click="$emit('use-entry')"
|
@click="$emit('use-entry')"
|
||||||
>
|
>
|
||||||
<span class="truncate">
|
<span class="truncate">
|
||||||
{{ `${entry.endpoint}` }}
|
{{ entry.request.endpoint }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
@@ -48,31 +48,53 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
|
import {
|
||||||
|
computed,
|
||||||
|
defineComponent,
|
||||||
|
PropType,
|
||||||
|
useContext,
|
||||||
|
} from "@nuxtjs/composition-api"
|
||||||
import findStatusGroup from "~/helpers/findStatusGroup"
|
import findStatusGroup from "~/helpers/findStatusGroup"
|
||||||
|
import { RESTHistoryEntry } from "~/newstore/history"
|
||||||
|
|
||||||
export default {
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
entry: { type: Object, default: () => {} },
|
entry: { type: Object as PropType<RESTHistoryEntry>, default: () => {} },
|
||||||
showMore: Boolean,
|
showMore: Boolean,
|
||||||
},
|
},
|
||||||
computed: {
|
setup(props) {
|
||||||
duration() {
|
const {
|
||||||
if (this.entry.meta.responseDuration) {
|
app: { i18n },
|
||||||
const responseDuration = this.entry.meta.responseDuration
|
} = useContext()
|
||||||
|
const $t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
|
const duration = computed(() => {
|
||||||
|
if (props.entry.responseMeta.duration) {
|
||||||
|
const responseDuration = props.entry.responseMeta.duration
|
||||||
|
if (!responseDuration) return ""
|
||||||
|
|
||||||
return responseDuration > 0
|
return responseDuration > 0
|
||||||
? `${this.$t("request.duration")}: ${responseDuration}ms`
|
? `${$t("request.duration").toString()}: ${responseDuration}ms`
|
||||||
: this.$t("error.no_duration")
|
: $t("error.no_duration").toString()
|
||||||
} else return this.$t("error.no_duration")
|
} else return $t("error.no_duration").toString()
|
||||||
},
|
})
|
||||||
entryStatus() {
|
|
||||||
const foundStatusGroup = findStatusGroup(this.entry.statusCode)
|
const entryStatus = computed(() => {
|
||||||
|
const foundStatusGroup = findStatusGroup(
|
||||||
|
props.entry.responseMeta.statusCode
|
||||||
|
)
|
||||||
return (
|
return (
|
||||||
foundStatusGroup || {
|
foundStatusGroup || {
|
||||||
className: "",
|
className: "",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
duration,
|
||||||
|
entryStatus,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export type HoppRESTReqBody =
|
|||||||
|
|
||||||
export interface HoppRESTRequest {
|
export interface HoppRESTRequest {
|
||||||
v: string
|
v: string
|
||||||
|
id?: string // Firebase Firestore ID
|
||||||
|
|
||||||
name: string
|
name: string
|
||||||
method: string
|
method: string
|
||||||
@@ -85,11 +86,19 @@ export function translateToNewRequest(x: any): HoppRESTRequest {
|
|||||||
// Old format
|
// Old format
|
||||||
const endpoint: string = `${x.url}${x.path}`
|
const endpoint: string = `${x.url}${x.path}`
|
||||||
|
|
||||||
const headers: HoppRESTHeader[] = x.headers
|
const headers: HoppRESTHeader[] = x.headers ?? []
|
||||||
|
|
||||||
// Remove old keys from params
|
// Remove old keys from params
|
||||||
const params: HoppRESTParam[] = (x.params as any[]).map(
|
const params: HoppRESTParam[] = (x.params ?? []).map(
|
||||||
({ key, value, active }) => ({
|
({
|
||||||
|
key,
|
||||||
|
value,
|
||||||
|
active,
|
||||||
|
}: {
|
||||||
|
key: string
|
||||||
|
value: string
|
||||||
|
active: boolean
|
||||||
|
}) => ({
|
||||||
key,
|
key,
|
||||||
value,
|
value,
|
||||||
active,
|
active,
|
||||||
@@ -117,6 +126,7 @@ export function translateToNewRequest(x: any): HoppRESTRequest {
|
|||||||
body,
|
body,
|
||||||
auth,
|
auth,
|
||||||
v: RESTReqSchemaVersion,
|
v: RESTReqSchemaVersion,
|
||||||
|
id: x.id, // Pass-through Firebase Firestore ID
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -2,9 +2,46 @@ import eq from "lodash/eq"
|
|||||||
import { pluck } from "rxjs/operators"
|
import { pluck } from "rxjs/operators"
|
||||||
import DispatchingStore, { defineDispatchers } from "./DispatchingStore"
|
import DispatchingStore, { defineDispatchers } from "./DispatchingStore"
|
||||||
import { completedRESTResponse$ } from "./RESTSession"
|
import { completedRESTResponse$ } from "./RESTSession"
|
||||||
|
import {
|
||||||
|
HoppRESTRequest,
|
||||||
|
translateToNewRequest,
|
||||||
|
} from "~/helpers/types/HoppRESTRequest"
|
||||||
|
|
||||||
|
export type RESTHistoryEntry = {
|
||||||
|
request: HoppRESTRequest
|
||||||
|
|
||||||
|
responseMeta: {
|
||||||
|
duration: number | null
|
||||||
|
statusCode: number | null
|
||||||
|
}
|
||||||
|
|
||||||
|
star: boolean
|
||||||
|
|
||||||
|
id?: string // For when Firebase Firestore is set
|
||||||
|
}
|
||||||
|
|
||||||
|
export function translateToNewRESTHistory(x: any): RESTHistoryEntry {
|
||||||
|
const request = translateToNewRequest(x)
|
||||||
|
const star = x.star ?? false
|
||||||
|
const duration = x.duration ?? null
|
||||||
|
const statusCode = x.status ?? null
|
||||||
|
|
||||||
|
const obj: RESTHistoryEntry = {
|
||||||
|
request,
|
||||||
|
star,
|
||||||
|
responseMeta: {
|
||||||
|
duration,
|
||||||
|
statusCode,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x.id) obj.id = x.id
|
||||||
|
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
export const defaultRESTHistoryState = {
|
export const defaultRESTHistoryState = {
|
||||||
state: [] as any[],
|
state: [] as RESTHistoryEntry[],
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultGraphqlHistoryState = {
|
export const defaultGraphqlHistoryState = {
|
||||||
@@ -16,21 +53,24 @@ export const HISTORY_LIMIT = 50
|
|||||||
type RESTHistoryType = typeof defaultRESTHistoryState
|
type RESTHistoryType = typeof defaultRESTHistoryState
|
||||||
type GraphqlHistoryType = typeof defaultGraphqlHistoryState
|
type GraphqlHistoryType = typeof defaultGraphqlHistoryState
|
||||||
|
|
||||||
const HistoryDispatcher = defineDispatchers({
|
const RESTHistoryDispatchers = defineDispatchers({
|
||||||
setEntries(
|
setEntries(_: RESTHistoryType, { entries }: { entries: RESTHistoryEntry[] }) {
|
||||||
_: RESTHistoryType | GraphqlHistoryType,
|
|
||||||
{ entries }: { entries: any[] }
|
|
||||||
) {
|
|
||||||
return {
|
return {
|
||||||
state: entries,
|
state: entries,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addEntry(currentVal: RESTHistoryType | GraphqlHistoryType, { entry }) {
|
addEntry(
|
||||||
|
currentVal: RESTHistoryType,
|
||||||
|
{ entry }: { entry: RESTHistoryEntry }
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
state: [entry, ...currentVal.state].slice(0, HISTORY_LIMIT),
|
state: [entry, ...currentVal.state].slice(0, HISTORY_LIMIT),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deleteEntry(currentVal: RESTHistoryType | GraphqlHistoryType, { entry }) {
|
deleteEntry(
|
||||||
|
currentVal: RESTHistoryType,
|
||||||
|
{ entry }: { entry: RESTHistoryEntry }
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
state: currentVal.state.filter((e) => !eq(e, entry)),
|
state: currentVal.state.filter((e) => !eq(e, entry)),
|
||||||
}
|
}
|
||||||
@@ -40,7 +80,46 @@ const HistoryDispatcher = defineDispatchers({
|
|||||||
state: [],
|
state: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toggleStar(currentVal: RESTHistoryType | GraphqlHistoryType, { entry }) {
|
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: any[] }) {
|
||||||
|
return {
|
||||||
|
state: entries,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addEntry(currentVal: GraphqlHistoryType, { entry }) {
|
||||||
|
return {
|
||||||
|
state: [entry, ...currentVal.state].slice(0, HISTORY_LIMIT),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deleteEntry(currentVal: GraphqlHistoryType, { entry }) {
|
||||||
|
return {
|
||||||
|
state: currentVal.state.filter((e) => !eq(e, entry)),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clearHistory() {
|
||||||
|
return {
|
||||||
|
state: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toggleStar(currentVal: GraphqlHistoryType, { entry }) {
|
||||||
return {
|
return {
|
||||||
state: currentVal.state.map((e) => {
|
state: currentVal.state.map((e) => {
|
||||||
if (eq(e, entry) && e.star !== undefined) {
|
if (eq(e, entry) && e.star !== undefined) {
|
||||||
@@ -57,32 +136,32 @@ const HistoryDispatcher = defineDispatchers({
|
|||||||
|
|
||||||
export const restHistoryStore = new DispatchingStore(
|
export const restHistoryStore = new DispatchingStore(
|
||||||
defaultRESTHistoryState,
|
defaultRESTHistoryState,
|
||||||
HistoryDispatcher
|
RESTHistoryDispatchers
|
||||||
)
|
)
|
||||||
|
|
||||||
export const graphqlHistoryStore = new DispatchingStore(
|
export const graphqlHistoryStore = new DispatchingStore(
|
||||||
defaultGraphqlHistoryState,
|
defaultGraphqlHistoryState,
|
||||||
HistoryDispatcher
|
GQLHistoryDispatchers
|
||||||
)
|
)
|
||||||
|
|
||||||
export const restHistory$ = restHistoryStore.subject$.pipe(pluck("state"))
|
export const restHistory$ = restHistoryStore.subject$.pipe(pluck("state"))
|
||||||
export const graphqlHistory$ = graphqlHistoryStore.subject$.pipe(pluck("state"))
|
export const graphqlHistory$ = graphqlHistoryStore.subject$.pipe(pluck("state"))
|
||||||
|
|
||||||
export function setRESTHistoryEntries(entries: any[]) {
|
export function setRESTHistoryEntries(entries: RESTHistoryEntry[]) {
|
||||||
restHistoryStore.dispatch({
|
restHistoryStore.dispatch({
|
||||||
dispatcher: "setEntries",
|
dispatcher: "setEntries",
|
||||||
payload: { entries },
|
payload: { entries },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addRESTHistoryEntry(entry: any) {
|
export function addRESTHistoryEntry(entry: RESTHistoryEntry) {
|
||||||
restHistoryStore.dispatch({
|
restHistoryStore.dispatch({
|
||||||
dispatcher: "addEntry",
|
dispatcher: "addEntry",
|
||||||
payload: { entry },
|
payload: { entry },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deleteRESTHistoryEntry(entry: any) {
|
export function deleteRESTHistoryEntry(entry: RESTHistoryEntry) {
|
||||||
restHistoryStore.dispatch({
|
restHistoryStore.dispatch({
|
||||||
dispatcher: "deleteEntry",
|
dispatcher: "deleteEntry",
|
||||||
payload: { entry },
|
payload: { entry },
|
||||||
@@ -96,7 +175,7 @@ export function clearRESTHistory() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function toggleRESTHistoryEntryStar(entry: any) {
|
export function toggleRESTHistoryEntryStar(entry: RESTHistoryEntry) {
|
||||||
restHistoryStore.dispatch({
|
restHistoryStore.dispatch({
|
||||||
dispatcher: "toggleStar",
|
dispatcher: "toggleStar",
|
||||||
payload: { entry },
|
payload: { entry },
|
||||||
@@ -144,10 +223,11 @@ completedRESTResponse$.subscribe((res) => {
|
|||||||
if (res.type === "loading" || res.type === "network_fail") return
|
if (res.type === "loading" || res.type === "network_fail") return
|
||||||
|
|
||||||
addRESTHistoryEntry({
|
addRESTHistoryEntry({
|
||||||
...res.req,
|
request: res.req,
|
||||||
type: res.type,
|
responseMeta: {
|
||||||
meta: res.meta,
|
duration: res.meta.responseDuration,
|
||||||
statusCode: res.statusCode,
|
statusCode: res.statusCode,
|
||||||
|
},
|
||||||
star: false,
|
star: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import {
|
|||||||
graphqlHistoryStore,
|
graphqlHistoryStore,
|
||||||
setRESTHistoryEntries,
|
setRESTHistoryEntries,
|
||||||
setGraphqlHistoryEntries,
|
setGraphqlHistoryEntries,
|
||||||
|
translateToNewRESTHistory,
|
||||||
} from "./history"
|
} from "./history"
|
||||||
import {
|
import {
|
||||||
restCollectionStore,
|
restCollectionStore,
|
||||||
@@ -109,7 +110,7 @@ function setupSettingsPersistence() {
|
|||||||
function setupHistoryPersistence() {
|
function setupHistoryPersistence() {
|
||||||
const restHistoryData = JSON.parse(
|
const restHistoryData = JSON.parse(
|
||||||
window.localStorage.getItem("history") || "[]"
|
window.localStorage.getItem("history") || "[]"
|
||||||
)
|
).map(translateToNewRESTHistory)
|
||||||
|
|
||||||
const graphqlHistoryData = JSON.parse(
|
const graphqlHistoryData = JSON.parse(
|
||||||
window.localStorage.getItem("graphqlHistory") || "[]"
|
window.localStorage.getItem("graphqlHistory") || "[]"
|
||||||
|
|||||||
1
package-lock.json
generated
1
package-lock.json
generated
@@ -5,6 +5,7 @@
|
|||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
|
"name": "hoppscotch",
|
||||||
"version": "1.12.0",
|
"version": "1.12.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apollo/client": "^3.4.8",
|
"@apollo/client": "^3.4.8",
|
||||||
|
|||||||
Reference in New Issue
Block a user