Skip to content

Commit

Permalink
feat: basic multi dir support
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 committed Mar 29, 2022
1 parent f166cfa commit 376d349
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 26 deletions.
4 changes: 2 additions & 2 deletions src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export async function writeTypes (nitro: Nitro) {
}

async function _build (nitro: Nitro) {
nitro.scannedMiddleware = await scanMiddleware(nitro.options.srcDir)
nitro.scannedMiddleware = await scanMiddleware(nitro)
await writeTypes(nitro)

consola.start('Building server...')
Expand Down Expand Up @@ -203,7 +203,7 @@ function startRollupWatcher (nitro: Nitro) {

async function _watch (nitro: Nitro) {
let watcher = startRollupWatcher(nitro)
nitro.scannedMiddleware = await scanMiddleware(nitro.options.srcDir,
nitro.scannedMiddleware = await scanMiddleware(nitro,
(middleware, event) => {
nitro.scannedMiddleware = middleware
if (['add', 'addDir'].includes(event)) {
Expand Down
4 changes: 4 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const NitroDefaults: NitroConfig = {
analyze: false,
experiments: {},
moduleSideEffects: ['unenv/runtime/polyfill/'],
scanDirs: [],
middleware: [],
modulesDir: [],
ignore: [],
Expand Down Expand Up @@ -80,6 +81,9 @@ export async function loadOptions (overrideConfig: NitroConfig = {}): Promise<Ni
}
options.modulesDir.push(resolve(options.rootDir, 'node_modules'))
options.modulesDir.push(resolve(pkgDir, 'node_modules'))
if (!options.scanDirs.length) {
options.scanDirs = [options.srcDir]
}

// Dev-only storage
if (options.dev) {
Expand Down
59 changes: 35 additions & 24 deletions src/server/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { resolve, join, extname } from 'pathe'
import { joinURL } from 'ufo'
import { withBase } from 'ufo'
import { globby } from 'globby'
import { watch } from 'chokidar'
import type { Middleware } from 'h3'
import { Nitro } from '../types'

export interface ServerMiddleware {
route: string
Expand All @@ -21,15 +22,13 @@ export interface ServerMiddleware {
promisify?: boolean // Default is true
}

function filesToMiddleware (files: string[], baseDir: string, baseURL: string, overrides?: Partial<ServerMiddleware>): ServerMiddleware[] {
return files.map((file) => {
const route = joinURL(
baseURL,
file
.slice(0, file.length - extname(file).length)
.replace(/\/index$/, '')
)
const handler = resolve(baseDir, file)
function filesToMiddleware (files: string[], baseDir: string, prefix: string, overrides?: Partial<ServerMiddleware>): ServerMiddleware[] {
return files.map((fileName: string) => {
const normalizedName = fileName
.slice(0, fileName.length - extname(fileName).length)
.replace(/\/index$/, '')
const route = withBase(normalizedName, prefix)
const handler = resolve(baseDir, fileName)
return {
route,
handler
Expand All @@ -39,25 +38,37 @@ function filesToMiddleware (files: string[], baseDir: string, baseURL: string, o
.map(m => ({ ...m, ...overrides }))
}

export function scanMiddleware (serverDir: string, onChange?: (results: ServerMiddleware[], event: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir', file: string) => void): Promise<ServerMiddleware[]> {
const pattern = '**/*.{ts,mjs,js,cjs}'
const globalDir = resolve(serverDir, 'middleware')
const apiDir = resolve(serverDir, 'api')
export function scanMiddleware (nitro: Nitro, onChange?: (results: ServerMiddleware[], event: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir', file: string) => void): Promise<ServerMiddleware[]> {
const globPattern = '**/*.{ts,mjs,js,cjs}'

type ScanOptions = { cwd: string, name: string, prefix: string, options: Partial<ServerMiddleware> }
const scanDirs: ScanOptions[] = []
for (const dir of nitro.options.scanDirs) {
scanDirs.push({
cwd: dir,
name: 'api',
prefix: '/api',
options: { lazy: true }
})
scanDirs.push({
cwd: dir,
name: 'middleware',
prefix: '/',
options: {}
})
}

const scan = async () => {
const globalFiles = await globby(pattern, { cwd: globalDir, dot: true })
const apiFiles = await globby(pattern, { cwd: apiDir, dot: true })
return [
...filesToMiddleware(globalFiles, globalDir, '/', { route: '/' }),
...filesToMiddleware(apiFiles, apiDir, '/api', { lazy: true })
]
const middleware = (await Promise.all(scanDirs.map(async (scanDir) => {
const cwd = join(scanDir.cwd, scanDir.name)
const files = await globby(globPattern, { cwd, dot: true })
return filesToMiddleware(files, cwd, scanDir.prefix, scanDir.options)
}))).flat()
return middleware
}

if (typeof onChange === 'function') {
const watcher = watch([
join(globalDir, pattern),
join(apiDir, pattern)
], { ignoreInitial: true })
const watcher = watch(scanDirs.map(dir => join(dir.cwd, dir.name, globPattern)), { ignoreInitial: true })
watcher.on('all', async (event, file) => {
onChange(await scan(), event, file)
})
Expand Down
1 change: 1 addition & 0 deletions src/types/nitro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export interface NitroOptions {

rootDir: string
srcDir: string
scanDirs: string[]
buildDir: string
generateDir: string
publicDir: string
Expand Down

0 comments on commit 376d349

Please sign in to comment.