Skip to content

Commit

Permalink
feat(server-routes): more code snippets
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Apr 18, 2023
1 parent c0cbfdb commit 40913b9
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 31 deletions.
3 changes: 2 additions & 1 deletion packages/devtools-ui-kit/src/unocss.ts
Expand Up @@ -90,10 +90,11 @@ export function unocssPreset(): Preset {
'n-bg-active': 'bg-gray:5',
'n-bg-hover': 'bg-gray:3',
'n-border-base': 'border-gray/20',

'n-transition': 'transition-all duration-200',
'n-focus-base': 'ring-2 ring-context/50',
'n-active-base': 'ring-3 ring-context/10',
'n-borderless': '!border-none !shadow-none',
'n-borderless': '!border-transparent !shadow-none',

// link
'n-link-base': 'underline underline-offset-2 underline-black/20 dark:underline-white/40',
Expand Down
26 changes: 17 additions & 9 deletions packages/devtools/client/components/CodeSnippets.vue
Expand Up @@ -19,23 +19,16 @@ watchEffect(() => {
<div flex="~ wrap" w-full>
<template v-for="cs, idx of codeSnippets" :key="idx">
<button
p2 border="r base"
px4 py2 border="r base"
hover="bg-active"
:class="cs === selected ? 'bg-active' : ''"
@click="selected = cs"
>
<div :class="cs === selected ? '' : 'op50' ">
<div :class="cs === selected ? '' : 'op50' " font-mono>
{{ cs.name }}
</div>
</button>
</template>
<div flex-auto />
<NButton v-if="selected?.docs" :to="selected.docs" target="_blank" icon="carbon-help" n="sm primary" border="none" my1 px-2>
Docs
</NButton>
<NButton v-if="selected" icon="carbon-copy" n="sm primary" border="none" my1 mr1 px-2 @click="copy(selected!.code)">
Copy
</NButton>
</div>

<div x-divider />
Expand All @@ -46,6 +39,21 @@ watchEffect(() => {
:lines="false"
w-full of-auto p3
/>
<div flex="~ gap-2" px3 pb2>
<NButton
icon="carbon-copy" n="sm primary"
my1 px-3 @click="copy(selected!.code)"
>
Copy
</NButton>
<NButton
v-if="selected?.docs" :to="selected.docs" target="_blank"
icon="carbon-catalog" n="sm primary"
my1 px-3
>
Docs
</NButton>
</div>
</template>
</div>
</template>
57 changes: 36 additions & 21 deletions packages/devtools/client/components/ServerRouteDetails.vue
@@ -1,5 +1,5 @@
<script setup lang="ts">
import type { ServerRouteInfo } from '~/../src/types'
import type { CodeSnippet, ServerRouteInfo } from '~/../src/types'
interface RouteParam {
[key: string]: string
Expand Down Expand Up @@ -121,22 +121,42 @@ async function fetchData() {
fetchTime.value = Date.now() - start
}
const rawFetchRequestCode = computed(() => {
const headers = routeHeaders.value.filter(({ key, value }) => key && value).map(({ key, value }) => ` '${key}': '${value}'`).join(',\n')
const codeSnippets = computed(() => {
const snippets: CodeSnippet[] = []
const items: string[] = []
const headers = routeHeaders.value
.filter(({ key, value }) => key && value && !(key === 'Content-Type' && value === 'application/json'))
.map(({ key, value }) => ` '${key}': '${value}'`).join(',\n')
if (routeMethod.value.toUpperCase() !== 'GET')
items.push(`method: '${routeMethod.value.toUpperCase()}'`)
if (headers)
items.push(`headers: {\n${headers}\n}`)
if (formattedBody.value)
items.push(`body: ${JSON.stringify(formattedBody.value, null, 2)}`)
return `await $fetch('${finalURL.value}', {
const options = items.length
? `, {
${items.join(',\n').split('\n').map(line => ` ${line}`).join('\n')}
})`
}`
: ''
snippets.push({
name: 'useFetch',
lang: 'javascript',
docs: 'https://nuxt.com/docs/api/composables/use-fetch',
code: `const { data, pending, error, refresh } = useFetch('${finalURL.value}'${options})`,
})
snippets.push({
name: '$fetch',
lang: 'javascript',
docs: 'https://nuxt.com/docs/api/utils/dollarfetch#fetch',
code: `await $fetch('${finalURL.value}'${options})`,
})
return snippets
})
const activeTab = ref(paramNames.value.length ? 'params' : 'query')
Expand Down Expand Up @@ -183,40 +203,40 @@ const methods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD']
<div flex="~ gap2" w-full items-center px4 pb2 text-center text-sm border="b base">
<NButton
v-if="paramNames.length"
:class="activeTab === 'params' ? 'text-primary n-primary' : 'border-transparent!'"
:class="activeTab === 'params' ? 'text-primary n-primary' : 'border-transparent! shadow-none!'"
@click="activeTab = 'params'"
>
<NIcon icon="i-carbon-text-selection" />
Params ({{ paramNames.length }})
</NButton>
<NButton
:class="activeTab === 'query' ? 'text-primary n-primary' : 'border-transparent!'"
:class="activeTab === 'query' ? 'text-primary n-primary' : 'border-transparent! shadow-none!'"
@click="activeTab = 'query'"
>
<NIcon icon="i-carbon-help" />
Query {{ queriesCount ? `(${queriesCount})` : '' }}
</NButton>
<NButton
v-if="routeMethod !== 'GET'"
:class="activeTab === 'body' ? 'text-primary n-primary' : 'border-transparent!'"
:class="activeTab === 'body' ? 'text-primary n-primary' : 'border-transparent! shadow-none!'"
@click="activeTab = 'body'"
>
<NIcon icon="i-carbon-document" />
Body
</NButton>
<NButton
:class="activeTab === 'headers' ? 'text-primary n-primary' : 'border-transparent!'"
:class="activeTab === 'headers' ? 'text-primary n-primary' : 'border-transparent! shadow-none!'"
@click="activeTab = 'headers'"
>
<NIcon icon="i-carbon-html-reference" />
Headers {{ headersCount ? `(${headersCount})` : '' }}
</NButton>
<NButton
:class="activeTab === 'snippet' ? 'text-primary n-primary' : 'border-transparent!'"
:class="activeTab === 'snippet' ? 'text-primary n-primary' : 'border-transparent! shadow-none!'"
@click="activeTab = 'snippet'"
>
<NIcon icon="carbon:code" />
Fetch Snippet
Snippets
</NButton>
<div flex-auto />
<NButton
Expand All @@ -243,15 +263,10 @@ const methods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD']
</template>
</div>
<div v-if="activeTab === 'snippet'" relative>
<NCodeBlock
p2 border="b base"
:code="rawFetchRequestCode"
lang="js"
/>
<NIconButton
icon="carbon:copy"
absolute bottom-4 right-4 z-100 p4
@click="copy(rawFetchRequestCode)"
<CodeSnippets
v-if="codeSnippets.length"
border="b base"
:code-snippets="codeSnippets"
/>
</div>
<div v-else-if="currentParams" px4 py2 flex="~ col gap-2" border="b base">
Expand Down
1 change: 1 addition & 0 deletions packages/devtools/client/pages/modules/server-routes.vue
Expand Up @@ -4,6 +4,7 @@ import Fuse from 'fuse.js'
definePageMeta({
icon: 'carbon-cloud',
title: 'Server Routes',
layout: 'full',
experimental: true,
shouldShow() {
return useServerRoutes().value?.length
Expand Down
3 changes: 3 additions & 0 deletions packages/devtools/client/server/api/echo.post.ts
@@ -0,0 +1,3 @@
export default defineEventHandler((ctx) => {
return ctx.node.req.read()
})
5 changes: 5 additions & 0 deletions packages/devtools/client/server/api/hello.get.ts
@@ -0,0 +1,5 @@
export default defineEventHandler(() => {
return {
msg: 'Hello World!',
}
})

0 comments on commit 40913b9

Please sign in to comment.