Skip to content

Commit

Permalink
feat: method support for rotue handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 committed Apr 7, 2022
1 parent 2e2e283 commit da35ab1
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 10 deletions.
3 changes: 3 additions & 0 deletions examples/api-routes/api/test.get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { defineEventHandler } from 'h3'

export default defineEventHandler(() => 'Test get handler')
3 changes: 3 additions & 0 deletions examples/api-routes/api/test.post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { defineEventHandler } from 'h3'

export default defineEventHandler(() => 'Test post handler')
1 change: 1 addition & 0 deletions examples/api-routes/routes/[...].ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export default defineEventHandler(() => {
<ul>
<li><a href="/api/hello">/api/hello</a></li>
<li><a href="/api/hello/world">/api/hello/world</a></li>
<li><a href="/api/test">/api/test</a></li>
</ul>
`
})
12 changes: 6 additions & 6 deletions src/rollup/plugins/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,31 @@ export function handlers (getHandlers: () => NitroEventHandler[]) {
return virtual({
'#nitro/virtual/server-handlers': {
load: () => {
const handler = getHandlers()
const handlers = getHandlers()

if (isDebug) {
const dumped = dumpHandler(handler)
const dumped = dumpHandler(handlers)
if (dumped !== lastDump) {
lastDump = dumped
if (handler.length) {
if (handlers.length) {
console.log(dumped)
}
}
}

// Imports take priority
const imports = unique(handler.filter(m => m.lazy === false).map(m => m.handler))
const imports = unique(handlers.filter(h => h.lazy === false).map(h => h.handler))

// Lazy imports should fill in the gaps
const lazyImports = unique(handler.filter(m => m.lazy !== false && !imports.includes(m.handler)).map(m => m.handler))
const lazyImports = unique(handlers.filter(h => h.lazy !== false && !imports.includes(h.handler)).map(h => h.handler))

const code = `
${imports.map(handler => `import ${getImportId(handler)} from '${handler}';`).join('\n')}
${lazyImports.map(handler => `const ${getImportId(handler)} = () => import('${handler}');`).join('\n')}
export const handlers = [
${handler.map(m => ` { route: '${m.route || ''}', handler: ${getImportId(m.handler)}, lazy: ${m.lazy || true} }`).join(',\n')}
${handlers.map(h => ` { route: '${h.route || ''}', handler: ${getImportId(h.handler)}, lazy: ${h.lazy || true}, method: ${JSON.stringify(h.method)} }`).join(',\n')}
];
`.trim()
// console.log(code)
Expand Down
3 changes: 2 additions & 1 deletion src/runtime/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function createNitroApp (): NitroApp {
if (h.route === '') {
h3App.use(config.app.baseURL, handler)
} else {
router.use(h.route, handler)
router.use(h.route, handler, h.method)
}
}

Expand All @@ -58,6 +58,7 @@ function createNitroApp (): NitroApp {
const localFetch = createLocalFetch(localCall, globalThis.fetch)

const $fetch = createFetch({ fetch: localFetch, Headers })
// @ts-ignore
globalThis.$fetch = $fetch

const app: NitroApp = {
Expand Down
1 change: 1 addition & 0 deletions src/runtime/virtual/server-handlers.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ interface HandlerDefinition {
route: string
lazy?: boolean
handler: CompatibilityEventHandler | (() => Promise<CompatibilityEventHandler>)
method?: 'connect'| 'delete'| 'get'| 'head'| 'options'| 'post'| 'put'| 'trace'
}

export const handlers: HandlerDefinition[]
17 changes: 14 additions & 3 deletions src/scan.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { resolve, join } from 'pathe'
import { globby } from 'globby'

import { withBase, withLeadingSlash, withoutTrailingSlash } from 'ufo'
import type { Nitro, NitroEventHandler } from './types'

export const GLOB_SCAN_PATTERN = '**/*.{ts,mjs,js,cjs}'
type FileInfo = { dir: string, path: string, fullPath: string }

const httpMethodRegex = /\.(connect|delete|get|head|options|post|put|trace)/

export async function scanHandlers (nitro: Nitro) {
const handlers = await Promise.all([
scanMiddleware(nitro),
Expand All @@ -28,15 +31,23 @@ export function scanMiddleware (nitro: Nitro) {
export function scanRoutes (nitro: Nitro, dir: string, prefix: string = '/') {
return scanServerDir(nitro, dir, (file) => {
let route = file.path
.replace(/\.[a-z]+$/, '')
.replace(/\.[a-zA-Z]+$/, '')
.replace(/index$/, '')
.replace(/\[...\]/g, '**')
.replace(/\[([a-z]+)\]/g, ':$1')
.replace(/\[([a-zA-Z]+)\]/g, ':$1')
route = withLeadingSlash(withoutTrailingSlash(withBase(route, prefix)))

let method
const methodMatch = route.match(httpMethodRegex)
if (methodMatch) {
route = route.substring(0, methodMatch.index)
method = methodMatch[1]
}

return {
handler: file.fullPath,
route
route,
method
}
})
}
Expand Down
7 changes: 7 additions & 0 deletions src/types/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import type { Handler } from 'h3'
export interface NitroEventHandler {
/**
* Path prefix or route
*
* If an empty string used, will be used as a middleware
*/
route?: string

Expand All @@ -16,6 +18,11 @@ export interface NitroEventHandler {
*
*/
handler: string

/**
* Router method matcher
*/
method?: string
}

export interface NitroDevEventHandler {
Expand Down

0 comments on commit da35ab1

Please sign in to comment.