Skip to content

Commit

Permalink
feat: support middleware, close #184
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Apr 29, 2023
1 parent c0b4bd6 commit 73ef44c
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 10 deletions.
3 changes: 2 additions & 1 deletion packages/devtools-kit/src/_types/rpc.ts
@@ -1,4 +1,4 @@
import type { NuxtLayout, NuxtOptions, NuxtPage } from 'nuxt/schema'
import type { NuxtApp, NuxtLayout, NuxtOptions, NuxtPage } from 'nuxt/schema'
import type { StorageMounts } from 'nitropack'
import type { StorageValue } from 'unstorage'
import type { Component } from 'vue'
Expand All @@ -19,6 +19,7 @@ export interface ServerFunctions {
getServerLayouts(): NuxtLayout[]
getStaticAssets(): Promise<AssetInfo[]>
getServerRoutes(): Promise<ServerRouteInfo[]>
getServerApp(): Promise<NuxtApp | undefined>

// Updates
checkForUpdateFor(name: string): Promise<PackageUpdateInfo | undefined>
Expand Down
26 changes: 17 additions & 9 deletions packages/devtools/client/components/FilepathItem.vue
@@ -1,26 +1,34 @@
<script setup lang="ts">
const props = defineProps<{
filepath: string
filepath?: string
lineBreak?: boolean
subpath?: boolean
override?: string
}>()
const openInEditor = useOpenInEditor()
const config = useServerConfig()
const parsed = computed(() => (props.filepath && config.value)
? parseReadablePath(props.filepath, config.value.rootDir)
: { path: props.filepath },
: { path: props.filepath || '' },
)
</script>

<template>
<button
font-mono hover:underline
:class="lineBreak ? '' : 'ws-nowrap of-hidden truncate'"
:title="filepath"
@click="openInEditor(filepath)"
<component
:is="filepath ? 'button' : 'span'"
:class="[
filepath ? 'hover:underline' : '',
lineBreak ? '' : 'ws-nowrap of-hidden truncate',
]"
font-mono
:title="override || filepath"
@click="filepath && openInEditor(filepath)"
>
<template v-if="parsed.moduleName">
<template v-if="override">
{{ override }}
</template>
<template v-else-if="parsed.moduleName">
<span>{{ parsed.moduleName }}</span>
<span v-if="subpath" op50>
{{ parsed.path.slice(parsed.moduleName.length) }}
Expand All @@ -29,5 +37,5 @@ const parsed = computed(() => (props.filepath && config.value)
<template v-else>
{{ parsed.path }}
</template>
</button>
</component>
</template>
17 changes: 17 additions & 0 deletions packages/devtools/client/components/RoutesTable.vue
Expand Up @@ -14,6 +14,8 @@ defineEmits<{
}>()
const openInEditor = useOpenInEditor()
const serverApp = useServerApp()
const sorted = computed(() => {
return [...props.pages].sort((a, b) => a.path.localeCompare(b.path))
})
Expand All @@ -23,6 +25,12 @@ function openLayout(name: string) {
if (layout)
openInEditor(layout.file)
}
function getMiddlewarePath(name: any) {
if (typeof name !== 'string')
return
return serverApp.value?.middleware.find(i => i.name === name)?.path
}
</script>

<template>
Expand All @@ -37,6 +45,9 @@ function openLayout(name: string) {
<th text-left>
Name
</th>
<th text-left>
Middleware
</th>
<th>
Layout
</th>
Expand Down Expand Up @@ -82,6 +93,12 @@ function openLayout(name: string) {
<td w-0 ws-nowrap pr-1 text-left font-mono text-sm op50>
{{ item.name }}
</td>
<td w-0 ws-nowrap pr-1 text-center font-mono text-sm op50>
<FilepathItem
:filepath="getMiddlewarePath(item.meta.middleware)"
:override="`${item.meta.middleware || '-'}`"
/>
</td>
<td w-0 ws-nowrap text-center font-mono text-sm>
<span v-if="item.meta.layout === false">-</span>
<button v-else-if="item.meta.layout" @click="openLayout(item.meta.layout as string)">
Expand Down
4 changes: 4 additions & 0 deletions packages/devtools/client/composables/state.ts
Expand Up @@ -71,6 +71,10 @@ export function useServerConfig() {
return useAsyncState('getServerConfig', () => rpc.getServerConfig())
}

export function useServerApp() {
return useAsyncState('getServerApp', () => rpc.getServerApp())
}

export function useCustomTabs() {
return useAsyncState('getCustomTabs', () => rpc.getCustomTabs())
}
Expand Down
8 changes: 8 additions & 0 deletions packages/devtools/client/content/pages.md
Expand Up @@ -3,3 +3,11 @@
One core feature of Nuxt is the file system router. Every Vue file inside the `pages/` directory creates a corresponding URL (or route) that displays the contents of the file. By using dynamic imports for each page, Nuxt leverages code-splitting to ship the minimum amount of JavaScript for the requested route.

[Learn more on the documentation](https://nuxt.com/docs/getting-started/routing)

----

# Middlewares

Nuxt provides a customizable route middleware framework you can use throughout your application, ideal for extracting code that you want to run before navigating to a particular route.

[Learn more on the documentation](https://nuxt.com/docs/guide/directory-structure/middleware)
39 changes: 39 additions & 0 deletions packages/devtools/client/pages/modules/pages.vue
Expand Up @@ -13,6 +13,7 @@ definePageMeta({
const router = useClientRouter()
const route = useClientRoute()
const config = useServerConfig()
const serverApp = useServerApp()
const serverPages = useServerPages()
const layouts = useLayouts()
Expand All @@ -28,6 +29,10 @@ const routes = computed((): RouteInfo[] => {
})
})
const middleware = computed(() => {
return serverApp.value?.middleware || []
})
const routeInput = ref('')
until(route).toBeTruthy().then((v) => {
Expand Down Expand Up @@ -116,6 +121,40 @@ function navigateToRoute(path: string) {
@navigate="navigateToRoute"
/>
</NSectionBlock>
<NSectionBlock
v-if="middleware.length"
icon="carbon:ibm-watson-studio"
text="Middleware"
:description="`${middleware.length} middleware registered in your application`"
padding="px13"
>
<table w-full>
<thead border="b base" h-7>
<tr>
<th text-left>
Name
</th>
<th text-left>
Path
</th>
</tr>
</thead>
<tr v-for="m of middleware" :key="m.path" h-7>
<td>
<span mr1>{{ m.name }}</span>
<Badge
v-if="m.global"
bg-green-400:10 text-green-400
title="Registered at runtime as a global component"
v-text="'global'"
/>
</td>
<td>
<FilepathItem :filepath="m.path" />
</td>
</tr>
</table>
</NSectionBlock>
</div>
<LaunchPage
v-else
Expand Down
7 changes: 7 additions & 0 deletions packages/devtools/src/server-rpc/general.ts
Expand Up @@ -14,6 +14,7 @@ export function setupGeneralRPC({ nuxt, refresh }: NuxtDevtoolsServerContext) {
const importPresets: Import[] = []
let importDirs: string[] = []
const serverPages: NuxtPage[] = []
let serverApp: NuxtApp | undefined

const serverHooks: Record<string, HookInfo> = setupHooksDebug(nuxt.hooks)

Expand Down Expand Up @@ -47,6 +48,9 @@ export function setupGeneralRPC({ nuxt, refresh }: NuxtDevtoolsServerContext) {

refresh('getServerPages')
})
nuxt.hook('app:resolve', (app) => {
serverApp = app
})
nuxt.hook('imports:sources', async (v) => {
const result = (await resolveBuiltinPresets(v)).flat()
importPresets.length = 0
Expand All @@ -67,6 +71,9 @@ export function setupGeneralRPC({ nuxt, refresh }: NuxtDevtoolsServerContext) {
getServerConfig() {
return nuxt.options
},
getServerApp() {

Check failure on line 74 in packages/devtools/src/server-rpc/general.ts

View workflow job for this annotation

GitHub Actions / ci

Type '() => NuxtApp | undefined' is not assignable to type '() => Promise<NuxtApp | undefined>'.
return serverApp
},
getComponents() {
return components
},
Expand Down

0 comments on commit 73ef44c

Please sign in to comment.