Skip to content

Commit 57deaf0

Browse files
authored
feat(server-routes): send from app instead of devtools, close #253 (#441)
1 parent cd95720 commit 57deaf0

File tree

8 files changed

+103
-806
lines changed

8 files changed

+103
-806
lines changed

packages/devtools-kit/build.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export default defineBuildConfig({
1616
'nitropack',
1717
'unimport',
1818
'unstorage',
19+
'ofetch',
1920
'vue',
2021
'vue-router',
2122
'nuxt/dist/app/nuxt',

packages/devtools-kit/src/_types/client-api.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { NuxtApp } from 'nuxt/dist/app/nuxt'
55
import type { Hookable } from 'hookable'
66
import type { BirpcReturn } from 'birpc'
77
import type { BuiltinLanguage } from 'shikiji'
8+
import type { $Fetch } from 'ofetch'
89
import type { ServerFunctions } from './rpc'
910
import type { HookInfo, LoadingTimeMetric, PluginMetric, VueInspectorClient, VueInspectorData } from './integrations'
1011
import type { TimelineMetrics } from './timeline-metrics'
@@ -94,6 +95,7 @@ export interface NuxtDevtoolsHostClient {
9495
appConfig: AppConfig
9596
colorMode: Ref<'dark' | 'light'>
9697
frameState: Ref<DevToolsFrameState>
98+
$fetch: $Fetch
9799
}
98100

99101
metrics: {

packages/devtools-kit/src/_types/options.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ export interface NuxtDevToolsOptions {
170170
selectedRoute: ServerRouteInfo | null
171171
view: 'tree' | 'list'
172172
inputDefaults: Record<string, ServerRouteInput[]>
173+
sendFrom: 'app' | 'devtools'
173174
}
174175
assets: {
175176
view: 'grid' | 'list'

packages/devtools-ui-kit/src/components/NSelect.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@ const input = useVModel(props, 'modelValue', emit, { passive: true })
2121

2222
<template>
2323
<div
24-
class="n-select flex flex items-center border n-border-base rounded px-2 py-1 focus-within:n-focus-base focus-within:border-context n-bg-base"
24+
class="n-select flex flex items-center border rounded px-2 py-1 focus-within:n-focus-base focus-within:border-context n-bg-base"
25+
:class="disabled ? 'border-gray:10' : 'n-border-base'"
2526
>
2627
<slot name="icon">
2728
<NIcon v-if="icon" :icon="icon" class="mr-0.4em text-1.1em op50" />
2829
</slot>
29-
<select v-model="input" :disabled="disabled" class="w-full flex-auto n-bg-base !outline-none">
30+
<select v-model="input" :disabled="disabled" class="w-full flex-auto n-bg-base !outline-none" :class="disabled ? 'appearance-none' : ''">
3031
<option v-if="placeholder" value="" disabled hidden>
3132
{{ placeholder }}
3233
</option>

packages/devtools/client/components/ServerRouteDetails.vue

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup lang="ts">
22
import JsonEditorVue from 'json-editor-vue'
33
import { createReusableTemplate } from '@vueuse/core'
4+
import type { $Fetch } from 'ofetch'
45
import type { CodeSnippet, ServerRouteInfo, ServerRouteInput } from '~/../src/types'
56
67
const props = defineProps<{
@@ -14,6 +15,7 @@ const emit = defineEmits<{
1415
const [DefineDefaultInputs, UseDefaultInputs] = createReusableTemplate()
1516
1617
const config = useServerConfig()
18+
const client = useClient()
1719
1820
const response = reactive({
1921
contentType: 'text/plain',
@@ -67,7 +69,16 @@ const routeInputs = reactive({
6769
headers: [{ key: 'Content-Type', value: 'application/json', type: 'string' }] as ServerRouteInput[],
6870
})
6971
const routeInputBodyJSON = ref({})
70-
const { inputDefaults } = useDevToolsOptions('serverRoutes')
72+
const {
73+
inputDefaults,
74+
sendFrom,
75+
} = useDevToolsOptions('serverRoutes')
76+
77+
const resolvedSendFrom = computed(() => {
78+
if (!client?.value?.app?.$fetch)
79+
return 'devtools'
80+
return sendFrom.value
81+
})
7182
7283
const methods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD']
7384
// https://github.com/unjs/h3/blob/main/src/utils/body.ts#L19
@@ -155,8 +166,12 @@ async function fetchData() {
155166
156167
const start = Date.now()
157168
169+
const f = resolvedSendFrom.value === 'app'
170+
? client.value!.app!.$fetch
171+
: $fetch as $Fetch
172+
158173
try {
159-
response.data = await $fetch(finalURL.value, {
174+
response.data = await f(finalURL.value, {
160175
method: routeMethod.value.toUpperCase() as any,
161176
headers: parsedHeader.value,
162177
query: parsedQuery.value,
@@ -298,14 +313,16 @@ const copy = useCopy()
298313
<div flex="~ col gap-2" flex-none p4 navbar-glass>
299314
<div flex="~ gap2 items-center">
300315
<NButton
301-
v-if="route.method" class="n-badge-base n-sm"
316+
v-if="route.method"
317+
class="n-badge-base n-sm"
302318
:class="getRequestMethodClass(routeMethod)"
303319
pointer-events-none font-mono tabindex="-1"
304320
>
305321
{{ routeMethod.toUpperCase() }}
306322
</NButton>
307323
<NSelect
308-
v-else v-model="routeMethod"
324+
v-else
325+
v-model="routeMethod"
309326
class="n-badge-base n-sm"
310327
:class="getRequestMethodClass(routeMethod)"
311328
>
@@ -320,15 +337,24 @@ const copy = useCopy()
320337
p="x5 y2"
321338
n="sm"
322339
/>
323-
<NButton
324-
v-tooltip="'Copy URL'"
325-
title="Copy URL"
326-
absolute right-2 top-1.5
327-
n="xs blue"
328-
icon="carbon:copy"
329-
:border="false"
330-
@click="copy(finalURL)"
331-
/>
340+
<div absolute right-2 top-1.5 flex="~ gap-1">
341+
<NButton
342+
v-tooltip="'Copy URL'"
343+
title="Copy URL"
344+
n="xs blue"
345+
icon="carbon:copy"
346+
:border="false"
347+
@click="copy(finalURL)"
348+
/>
349+
<NButton
350+
v-tooltip="'Open in Editor'"
351+
title="Open in Editor"
352+
icon="carbon-launch"
353+
n="xs blue"
354+
:border="false"
355+
@click="openInEditor(route.filepath)"
356+
/>
357+
</div>
332358
</div>
333359
<NButton n="primary solid" @click="fetchData">
334360
<NIcon icon="carbon:send" />
@@ -351,13 +377,21 @@ const copy = useCopy()
351377
</span>
352378
</NButton>
353379
<div flex-auto />
354-
<NButton
355-
v-tooltip="'Open in Editor'"
356-
title="Open in Editor"
357-
@click="openInEditor(route.filepath)"
380+
<div text-xs op50>
381+
Send from
382+
</div>
383+
<NSelect
384+
v-model="resolvedSendFrom"
385+
class="n-xs"
386+
:disabled="!client?.app?.$fetch"
358387
>
359-
<NIcon icon="carbon-launch" />
360-
</NButton>
388+
<option value="app">
389+
App
390+
</option>
391+
<option value="devtools">
392+
DevTools
393+
</option>
394+
</NSelect>
361395
</div>
362396
<div
363397
v-if="activeTab === 'params'"

packages/devtools/src/constant.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export const defaultTabOptions: NuxtDevToolsOptions = {
5050
body: [],
5151
headers: [],
5252
},
53+
sendFrom: 'app',
5354
},
5455
assets: {
5556
view: 'grid',

packages/devtools/src/runtime/plugins/view/client.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { computed, createApp, h, markRaw, nextTick, ref, shallowReactive, shallo
33
import { createHooks } from 'hookable'
44
import { debounce } from 'perfect-debounce'
55
import type { Router } from 'vue-router'
6+
import type { $Fetch } from 'ofetch'
67
import type { NuxtDevtoolsHostClient, TimelineEventRoute, TimelineMetrics } from '../../../types'
78
import { initTimelineMetrics } from '../../function-metrics-helpers'
89
import Main from './Main.vue'
@@ -92,6 +93,7 @@ export async function setupDevToolsClient({
9293
},
9394
colorMode,
9495
frameState: state,
96+
$fetch: globalThis.$fetch as $Fetch,
9597
},
9698

9799
metrics: {

0 commit comments

Comments
 (0)