2021-02-18 16:06:58 +00:00
|
|
|
import { resolve, join, extname } from 'upath'
|
|
|
|
import { joinURL } from 'ufo'
|
|
|
|
import globby from 'globby'
|
|
|
|
import { watch } from 'chokidar'
|
|
|
|
|
|
|
|
export interface ServerMiddleware {
|
|
|
|
route: string
|
|
|
|
handle: string
|
|
|
|
lazy?: boolean // Default is true
|
|
|
|
promisify?: boolean // Default is true
|
|
|
|
}
|
|
|
|
|
|
|
|
function filesToMiddleware (files: string[], baseDir: string, basePath: string, overrides?: Partial<ServerMiddleware>): ServerMiddleware[] {
|
|
|
|
return files.map((file) => {
|
|
|
|
const route = joinURL(basePath, file.substr(0, file.length - extname(file).length))
|
|
|
|
const handle = resolve(baseDir, file)
|
|
|
|
return {
|
|
|
|
route,
|
|
|
|
handle
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.sort((a, b) => a.route.localeCompare(b.route))
|
|
|
|
.map(m => ({ ...m, ...overrides }))
|
|
|
|
}
|
|
|
|
|
2021-02-19 14:01:08 +00:00
|
|
|
export function scanMiddleware (serverDir: string, onChange?: (results: ServerMiddleware[], event: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir', file: string) => void): Promise<ServerMiddleware[]> {
|
2021-02-18 16:06:58 +00:00
|
|
|
const pattern = '**/*.{js,ts}'
|
|
|
|
const globalDir = resolve(serverDir, 'middleware')
|
|
|
|
const apiDir = resolve(serverDir, 'api')
|
|
|
|
|
|
|
|
const scan = async () => {
|
|
|
|
const globalFiles = await globby(pattern, { cwd: globalDir })
|
|
|
|
const apiFiles = await globby(pattern, { cwd: apiDir })
|
|
|
|
return [
|
|
|
|
...filesToMiddleware(globalFiles, globalDir, '/', { route: '/' }),
|
|
|
|
...filesToMiddleware(apiFiles, apiDir, '/api', { lazy: true })
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof onChange === 'function') {
|
|
|
|
const watcher = watch([
|
|
|
|
join(globalDir, pattern),
|
|
|
|
join(apiDir, pattern)
|
|
|
|
], { ignoreInitial: true })
|
|
|
|
watcher.on('all', async (event, file) => {
|
|
|
|
onChange(await scan(), event, file)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
return scan()
|
|
|
|
}
|
|
|
|
|
|
|
|
export function resolveMiddleware (serverMiddleware: any[], resolvePath: (string) => string) {
|
|
|
|
const middleware: ServerMiddleware[] = []
|
|
|
|
const legacyMiddleware: ServerMiddleware[] = []
|
|
|
|
|
|
|
|
for (let m of serverMiddleware) {
|
|
|
|
if (typeof m === 'string') { m = { handler: m } }
|
|
|
|
const route = m.path || m.route || '/'
|
|
|
|
const handle = m.handler || m.handle
|
|
|
|
if (typeof handle !== 'string' || typeof route !== 'string') {
|
|
|
|
legacyMiddleware.push(m)
|
|
|
|
} else {
|
2021-02-22 10:37:29 +00:00
|
|
|
delete m.handler
|
|
|
|
delete m.path
|
2021-02-18 16:06:58 +00:00
|
|
|
middleware.push({
|
|
|
|
...m,
|
|
|
|
handle: resolvePath(handle),
|
|
|
|
route
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
middleware,
|
|
|
|
legacyMiddleware
|
|
|
|
}
|
|
|
|
}
|