crystal-node-runtime

Descoberta automática de rotas (report-routes-runtime)

Módulo independente para aplicações Node/Express que organizam relatórios em pastas *Report.

Convenção

Pasta Rota (com basePath: '/')
lotes/dicon/termo/cienciaReport /lotes/dicon/termo/ciencia
financeiro/extratoReport /financeiro/extrato
vendas/pedidoClienteReport /vendas/pedidoCliente

API

const {
  discoverReportRoutes,
  mountReportRoutes,
  createReportRouter,
  toRoutePath,
  stripReportSuffix
} = require('@crystal-node/runtime');

// ou:
// const routes = require('@crystal-node/runtime/report-routes-runtime');

discoverReportRoutes(rootDir, options?)

Retorna array:

{
  folderName: 'cienciaReport',
  absolutePath: '/abs/.../cienciaReport',
  relativePath: 'lotes/dicon/termo/cienciaReport',
  route: '/lotes/dicon/termo/ciencia',
  controllerPath: '/abs/.../controller.js',
  hasController: true
}

mountReportRoutes(appOrRouter, options)

Registra cada controller no Express (app.post(route, handler) por padrão).

createReportRouter(options)

Atalho que cria um express.Router() e monta as rotas nele.
Requer express instalado na app hospedeira: https://www.npmjs.com/package/express

Opções

Opção Default Descrição
rootDir Pasta raiz a varrer (obrigatório)
basePath '/' Prefixo da rota ('/api', '/reports', …)
method / methods 'post' Verbo(s) HTTP
suffix 'Report' Sufixo que identifica a pasta
controllerFile 'controller.js' Arquivo do handler
requireController true Ignora pasta sem controller
stripReportFromAllSegments false Se true, remove Report de qualquer segmento do caminho
ignore ['node_modules','.git','puppeteer-debug'] Pastas ignoradas
onConflict lança erro Callback se duas pastas gerarem a mesma rota
loadController require(path) Customiza o carregamento do handler

Exemplos

Montar na raiz do app

mountReportRoutes(app, {
  rootDir: path.join(__dirname, 'src/core'),
  method: 'post'
});

Prefixo /api + GET e POST

mountReportRoutes(app, {
  rootDir: path.join(__dirname, 'src/core'),
  basePath: '/api',
  methods: ['get', 'post']
});

Router isolado

const reportRouter = createReportRouter({
  rootDir: path.join(__dirname, 'src/core'),
  basePath: '/' // relativo ao ponto de mount
});
app.use('/reports', reportRouter);
// cienciaReport vira POST /reports/lotes/dicon/termo/ciencia

Conflitos

Se duas pastas diferentes produzirem a mesma rota, a descoberta lança erro.
Isso costuma indicar pastas renomeadas de forma ambígua (ex.: fooReport e foo + algo que colida). Use onConflict só se souber o que está fazendo.

Uso sem Express

discoverReportRoutes é agnóstico de framework. Você pode iterar o resultado e registrar no Fastify, Koa, etc.:

const found = discoverReportRoutes(rootDir);
for (const item of found) {
  const handler = require(item.controllerPath);
  // fastify.post(item.route, handler) etc.
}