Initial lens implementation
This commit is contained in:
42
components/lenses/ResponseBodyRenderer.vue
Normal file
42
components/lenses/ResponseBodyRenderer.vue
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<tabs>
|
||||||
|
<tab
|
||||||
|
v-for="(lens, index) in validLenses"
|
||||||
|
:id="lens.lensName"
|
||||||
|
:key="lens.lensName"
|
||||||
|
:label="lens.lensName"
|
||||||
|
:selected="index === 0"
|
||||||
|
>
|
||||||
|
<component :is="lens.renderer" :response="response" />
|
||||||
|
</tab>
|
||||||
|
</tabs>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import getSuitableLenses from "../../helpers/lenses/lenses"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
// Lens Renderers
|
||||||
|
raw: () => import("../lenses/renderers/RawLensRenderer"),
|
||||||
|
json: () => import("../lenses/renderers/JSONLensRenderer"),
|
||||||
|
imageres: () => import("../lenses/renderers/ImageLensRenderer"),
|
||||||
|
htmlres: () => import("../lenses/renderers/HTMLLensRenderer"),
|
||||||
|
|
||||||
|
tabs: () => import("../ui/tabs"),
|
||||||
|
tab: () => import("../ui/tab"),
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
response: {},
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
validLenses() {
|
||||||
|
return getSuitableLenses(this.response)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
36
components/lenses/renderers/HTMLLensRenderer.vue
Normal file
36
components/lenses/renderers/HTMLLensRenderer.vue
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<template>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<Editor
|
||||||
|
:value="responseBodyText"
|
||||||
|
:lang="'html'"
|
||||||
|
:options="{
|
||||||
|
maxLines: 16,
|
||||||
|
minLines: '16',
|
||||||
|
fontSize: '16px',
|
||||||
|
autoScrollEditorIntoView: true,
|
||||||
|
readOnly: true,
|
||||||
|
showPrintMargin: false,
|
||||||
|
useWorker: false,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import AceEditor from "../../ui/ace-editor"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Editor: AceEditor,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
response: {},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
responseBodyText() {
|
||||||
|
return new TextDecoder("utf-8").decode(this.response.body)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
56
components/lenses/renderers/ImageLensRenderer.vue
Normal file
56
components/lenses/renderers/ImageLensRenderer.vue
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<template>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<img :src="imageSource" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
response: {},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
imageSource: "",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
response: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newValue) {
|
||||||
|
console.log("wetch")
|
||||||
|
this.imageSource = ""
|
||||||
|
|
||||||
|
const buf = this.response.body
|
||||||
|
const bytes = new Uint8Array(buf)
|
||||||
|
const blob = new Blob([bytes.buffer])
|
||||||
|
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.onload = (e) => {
|
||||||
|
console.log(e.target.result)
|
||||||
|
this.imageSource = e.target.result
|
||||||
|
}
|
||||||
|
reader.readAsDataURL(blob)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
console.log("mount")
|
||||||
|
this.imageSource = ""
|
||||||
|
|
||||||
|
console.log(this.response)
|
||||||
|
const buf = this.response.body
|
||||||
|
const bytes = new Uint8Array(buf)
|
||||||
|
const blob = new Blob([bytes.buffer])
|
||||||
|
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.onload = (e) => {
|
||||||
|
console.log(e.target.result)
|
||||||
|
this.imageSource = e.target.result
|
||||||
|
}
|
||||||
|
reader.readAsDataURL(blob)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
45
components/lenses/renderers/JSONLensRenderer.vue
Normal file
45
components/lenses/renderers/JSONLensRenderer.vue
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<template>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<Editor
|
||||||
|
:value="responseBodyText"
|
||||||
|
:lang="'json'"
|
||||||
|
:options="{
|
||||||
|
maxLines: 16,
|
||||||
|
minLines: '16',
|
||||||
|
fontSize: '16px',
|
||||||
|
autoScrollEditorIntoView: true,
|
||||||
|
readOnly: true,
|
||||||
|
showPrintMargin: false,
|
||||||
|
useWorker: false,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import AceEditor from "../../ui/ace-editor"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Editor: AceEditor,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
response: {},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
responseBodyText() {
|
||||||
|
try {
|
||||||
|
return JSON.stringify(
|
||||||
|
JSON.parse(new TextDecoder("utf-8").decode(new Uint8Array(this.response.body))),
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
} catch (e) {
|
||||||
|
// Most probs invalid JSON was returned, so drop prettification (should we warn ?)
|
||||||
|
return new TextDecoder("utf-8").decode(new Uint8Array(this.response.body))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
36
components/lenses/renderers/RawLensRenderer.vue
Normal file
36
components/lenses/renderers/RawLensRenderer.vue
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<template>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<Editor
|
||||||
|
:value="responseBodyText"
|
||||||
|
:lang="'plain_text'"
|
||||||
|
:options="{
|
||||||
|
maxLines: 16,
|
||||||
|
minLines: '16',
|
||||||
|
fontSize: '16px',
|
||||||
|
autoScrollEditorIntoView: true,
|
||||||
|
readOnly: true,
|
||||||
|
showPrintMargin: false,
|
||||||
|
useWorker: false,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import AceEditor from "../../ui/ace-editor"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Editor: AceEditor,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
response: {},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
responseBodyText() {
|
||||||
|
return new TextDecoder("utf-8").decode(new Uint8Array(this.response.body))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -76,6 +76,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
lang(value) {
|
lang(value) {
|
||||||
|
console.log("ace/mode/" + value)
|
||||||
this.editor.getSession().setMode("ace/mode/" + value)
|
this.editor.getSession().setMode("ace/mode/" + value)
|
||||||
},
|
},
|
||||||
options(value) {
|
options(value) {
|
||||||
|
|||||||
7
helpers/lenses/htmlLens.js
Normal file
7
helpers/lenses/htmlLens.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
const htmlLens = {
|
||||||
|
lensName: "HTML",
|
||||||
|
supportedContentTypes: ["text/html"],
|
||||||
|
renderer: "htmlres",
|
||||||
|
}
|
||||||
|
|
||||||
|
export default htmlLens
|
||||||
12
helpers/lenses/imageLens.js
Normal file
12
helpers/lenses/imageLens.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
const imageLens = {
|
||||||
|
lensName: "Image",
|
||||||
|
supportedContentTypes: [
|
||||||
|
"image/gif",
|
||||||
|
"image/jpeg",
|
||||||
|
"image/png",
|
||||||
|
// TODO : Add more image types!
|
||||||
|
],
|
||||||
|
renderer: "imageres",
|
||||||
|
}
|
||||||
|
|
||||||
|
export default imageLens
|
||||||
7
helpers/lenses/jsonLens.js
Normal file
7
helpers/lenses/jsonLens.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
const jsonLens = {
|
||||||
|
lensName: "JSON",
|
||||||
|
supportedContentTypes: ["application/json", "application/hal+json", "application/vnd.api+json"],
|
||||||
|
renderer: "json",
|
||||||
|
}
|
||||||
|
|
||||||
|
export default jsonLens
|
||||||
37
helpers/lenses/lenses.js
Normal file
37
helpers/lenses/lenses.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import jsonLens from "./jsonLens"
|
||||||
|
import rawLens from "./rawLens"
|
||||||
|
import imageLens from "./imageLens"
|
||||||
|
import htmlLens from "./htmlLens"
|
||||||
|
|
||||||
|
const lenses = [
|
||||||
|
jsonLens,
|
||||||
|
imageLens,
|
||||||
|
htmlLens,
|
||||||
|
|
||||||
|
// Keep Raw Lens as the last option
|
||||||
|
rawLens,
|
||||||
|
]
|
||||||
|
|
||||||
|
function getSuitableLenses(response) {
|
||||||
|
const result = []
|
||||||
|
|
||||||
|
if (response && response.headers && response.headers["content-type"]) {
|
||||||
|
const properContentType = response.headers["content-type"].split(";")[0]
|
||||||
|
|
||||||
|
for (const lens of lenses) {
|
||||||
|
if (
|
||||||
|
lens.supportedContentTypes === null ||
|
||||||
|
lens.supportedContentTypes.includes(properContentType)
|
||||||
|
) {
|
||||||
|
result.push(lens)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We don't know the content type, so lets just add rawLens
|
||||||
|
result.push(rawLens)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
export default getSuitableLenses
|
||||||
7
helpers/lenses/rawLens.js
Normal file
7
helpers/lenses/rawLens.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
const rawLens = {
|
||||||
|
lensName: "Raw",
|
||||||
|
supportedContentTypes: null,
|
||||||
|
renderer: "raw",
|
||||||
|
}
|
||||||
|
|
||||||
|
export default rawLens
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import axios from "axios"
|
import axios from "axios"
|
||||||
|
import { isJSONContentType } from "../utils/contenttypes"
|
||||||
|
|
||||||
let cancelSource = axios.CancelToken.source()
|
let cancelSource = axios.CancelToken.source()
|
||||||
|
|
||||||
@@ -34,28 +35,9 @@ const axiosWithoutProxy = async (req, _store) => {
|
|||||||
const res = await axios({
|
const res = await axios({
|
||||||
...req,
|
...req,
|
||||||
cancelToken: cancelSource.token,
|
cancelToken: cancelSource.token,
|
||||||
transformResponse: [
|
responseType: "arraybuffer",
|
||||||
(data, headers) => {
|
|
||||||
// If the response has a JSON content type, try parsing it
|
|
||||||
if (
|
|
||||||
headers["content-type"] &&
|
|
||||||
(headers["content-type"].startsWith("application/json") ||
|
|
||||||
headers["content-type"].startsWith("application/vnd.api+json") ||
|
|
||||||
headers["content-type"].startsWith("application/hal+json"))
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
const jsonData = JSON.parse(data)
|
|
||||||
return jsonData
|
|
||||||
} catch (e) {
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Else return the string itself without any transformations
|
|
||||||
return data
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return res
|
return res
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (axios.isCancel(e)) {
|
if (axios.isCancel(e)) {
|
||||||
|
|||||||
@@ -952,6 +952,10 @@
|
|||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<div v-if="response.body">
|
||||||
|
<response-renderer :response="response" />
|
||||||
|
</div>
|
||||||
|
<!--
|
||||||
<ul v-if="response.body">
|
<ul v-if="response.body">
|
||||||
<li>
|
<li>
|
||||||
<div class="flex-wrap">
|
<div class="flex-wrap">
|
||||||
@@ -1023,6 +1027,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
-->
|
||||||
<ul v-for="(value, key) in response.headers" :key="key" class="response-headers">
|
<ul v-for="(value, key) in response.headers" :key="key" class="response-headers">
|
||||||
<li>
|
<li>
|
||||||
<label :for="key">{{ key }}</label>
|
<label :for="key">{{ key }}</label>
|
||||||
@@ -1420,12 +1425,13 @@ export default {
|
|||||||
collections: () => import("~/components/collections"),
|
collections: () => import("~/components/collections"),
|
||||||
saveRequestAs: () => import("~/components/collections/saveRequestAs"),
|
saveRequestAs: () => import("~/components/collections/saveRequestAs"),
|
||||||
Editor: AceEditor,
|
Editor: AceEditor,
|
||||||
environments: () => import("~/components/environments"),
|
environments: () => import("../components/environments"),
|
||||||
inputform: () => import("~/components/firebase/inputform"),
|
inputform: () => import("../components/firebase/inputform"),
|
||||||
notes: () => import("~/components/firebase/feeds"),
|
notes: () => import("../components/firebase/feeds"),
|
||||||
login: () => import("~/components/firebase/login"),
|
login: () => import("../components/firebase/login"),
|
||||||
tabs: () => import("~/components/ui/tabs"),
|
tabs: () => import("../components/ui/tabs"),
|
||||||
tab: () => import("~/components/ui/tab"),
|
tab: () => import("../components/ui/tab"),
|
||||||
|
"response-renderer": () => import("../components/lenses/ResponseBodyRenderer"),
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user