diff --git a/src/client/pages/api-console.vue b/src/client/pages/api-console.vue new file mode 100644 index 0000000000000000000000000000000000000000..2b05038acf2d0285246f2a50e72757cf4c5569f0 --- /dev/null +++ b/src/client/pages/api-console.vue @@ -0,0 +1,96 @@ +<template> +<div> +<section class="_section"> + <MkInput v-model:value="endpoint" :datalist="endpoints" @update:value="onEndpointChange()"> + <span>Endpoint</span> + </MkInput> + <MkTextarea v-model:value="body" code> + <span>Params (JSON or JSON5)</span> + </MkTextarea> + <MkSwitch v-model:value="withCredential"> + With credential + </MkSwitch> + <MkButton primary full @click="send" :disabled="sending"> + <template v-if="sending"><MkEllipsis/></template> + <template v-else><Fa :icon="faPaperPlane"/> Send</template> + </MkButton> +</section> +<section class="_section" v-if="res"> + <MkTextarea v-model:value="res" code readonly tall> + <span>Response</span> + </MkTextarea> +</section> +</div> +</template> + +<script lang="ts"> +import { defineComponent } from 'vue'; +import { faTerminal, faPaperPlane } from '@fortawesome/free-solid-svg-icons'; +import * as JSON5 from 'json5'; +import MkButton from '@/components/ui/button.vue'; +import MkInput from '@/components/ui/input.vue'; +import MkTextarea from '@/components/ui/textarea.vue'; +import MkSwitch from '@/components/ui/switch.vue'; +import * as os from '@/os'; + +export default defineComponent({ + components: { + MkButton, MkInput, MkTextarea, MkSwitch, + }, + + data() { + return { + INFO: { + header: [{ + title: 'API console', + icon: faTerminal + }] + }, + + endpoint: '', + body: '{}', + res: null, + sending: false, + endpoints: [], + withCredential: true, + + faPaperPlane + }; + }, + + created() { + os.api('endpoints').then(endpoints => { + this.endpoints = endpoints; + }); + }, + + methods: { + send() { + this.sending = true; + os.api(this.endpoint, JSON5.parse(this.body)).then(res => { + this.sending = false; + this.res = JSON5.stringify(res, null, 2); + }, err => { + this.sending = false; + this.res = JSON5.stringify(err, null, 2); + }); + }, + + onEndpointChange() { + os.api('endpoint', { endpoint: this.endpoint }, this.withCredential ? undefined : null).then(endpoint => { + const body = {}; + for (const p of endpoint.params) { + body[p.name] = + p.type === 'String' ? '' : + p.type === 'Number' ? 0 : + p.type === 'Boolean' ? false : + p.type === 'Array' ? [] : + p.type === 'Object' ? {} : + null; + } + this.body = JSON5.stringify(body, null, 2); + }); + } + } +}); +</script> diff --git a/src/client/pages/settings/api.vue b/src/client/pages/settings/api.vue index 326ba900629fac938794cbd376a1506bf1ea0ddb..4f14aa1ba7cdbac7094a9f402e43364e3aab23a1 100644 --- a/src/client/pages/settings/api.vue +++ b/src/client/pages/settings/api.vue @@ -1,9 +1,14 @@ <template> -<section class="_section"> - <div class="_content"> - <MkButton @click="generateToken">{{ $t('generateAccessToken') }}</MkButton> +<div> + <div class="_section"> + <div class="_content"> + <MkButton @click="generateToken">{{ $t('generateAccessToken') }}</MkButton> + </div> </div> -</section> + <div class="_section"> + <MkA to="/api-console">API console</MkA> + </div> +</div> </template> <script lang="ts"> diff --git a/src/client/router.ts b/src/client/router.ts index ef540f0d4ba87e52499c9fe1bbf3505c99cd7807..56320d224eb49159d45eb18729541922ceafb5b3 100644 --- a/src/client/router.ts +++ b/src/client/router.ts @@ -70,6 +70,7 @@ export const router = createRouter({ { path: '/instance/abuses', component: page('instance/abuses') }, { path: '/notes/:note', name: 'note', component: page('note'), props: route => ({ noteId: route.params.note }) }, { path: '/tags/:tag', component: page('tag'), props: route => ({ tag: route.params.tag }) }, + { path: '/api-console', component: page('api-console') }, { path: '/auth/:token', component: page('auth') }, { path: '/miauth/:session', component: page('miauth') }, { path: '/authorize-follow', component: page('follow') },