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) {
|
||||
console.log("ace/mode/" + value)
|
||||
this.editor.getSession().setMode("ace/mode/" + 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 { isJSONContentType } from "../utils/contenttypes"
|
||||
|
||||
let cancelSource = axios.CancelToken.source()
|
||||
|
||||
@@ -34,28 +35,9 @@ const axiosWithoutProxy = async (req, _store) => {
|
||||
const res = await axios({
|
||||
...req,
|
||||
cancelToken: cancelSource.token,
|
||||
transformResponse: [
|
||||
(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
|
||||
},
|
||||
],
|
||||
responseType: "arraybuffer",
|
||||
})
|
||||
|
||||
return res
|
||||
} catch (e) {
|
||||
if (axios.isCancel(e)) {
|
||||
|
||||
@@ -952,6 +952,10 @@
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
<div v-if="response.body">
|
||||
<response-renderer :response="response" />
|
||||
</div>
|
||||
<!--
|
||||
<ul v-if="response.body">
|
||||
<li>
|
||||
<div class="flex-wrap">
|
||||
@@ -1023,6 +1027,7 @@
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
-->
|
||||
<ul v-for="(value, key) in response.headers" :key="key" class="response-headers">
|
||||
<li>
|
||||
<label :for="key">{{ key }}</label>
|
||||
@@ -1420,12 +1425,13 @@ export default {
|
||||
collections: () => import("~/components/collections"),
|
||||
saveRequestAs: () => import("~/components/collections/saveRequestAs"),
|
||||
Editor: AceEditor,
|
||||
environments: () => import("~/components/environments"),
|
||||
inputform: () => import("~/components/firebase/inputform"),
|
||||
notes: () => import("~/components/firebase/feeds"),
|
||||
login: () => import("~/components/firebase/login"),
|
||||
tabs: () => import("~/components/ui/tabs"),
|
||||
tab: () => import("~/components/ui/tab"),
|
||||
environments: () => import("../components/environments"),
|
||||
inputform: () => import("../components/firebase/inputform"),
|
||||
notes: () => import("../components/firebase/feeds"),
|
||||
login: () => import("../components/firebase/login"),
|
||||
tabs: () => import("../components/ui/tabs"),
|
||||
tab: () => import("../components/ui/tab"),
|
||||
"response-renderer": () => import("../components/lenses/ResponseBodyRenderer"),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user