diff --git a/packages/ingest/src/Router.ts b/packages/ingest/src/Router.ts index f233a2f..93bb90f 100644 --- a/packages/ingest/src/Router.ts +++ b/packages/ingest/src/Router.ts @@ -4,7 +4,9 @@ import EventRouter from '@stackpress/lib/EventRouter'; //common import type { RouterAction, + RouterActions, RouterEmitter, + RouterImport, RouterQueueArgs } from './types'; import Request from './Request'; @@ -52,7 +54,7 @@ export default class Router< */ public all( path: string, - action: RouterAction, + action: RouterActions, priority?: number ) { return this.route('[A-Z]+', path, action, priority); @@ -63,7 +65,7 @@ export default class Router< */ public connect( path: string, - action: RouterAction, + action: RouterActions, priority?: number ) { return this.route('CONNECT', path, action, priority); @@ -74,7 +76,7 @@ export default class Router< */ public delete( path: string, - action: RouterAction, + action: RouterActions, priority?: number ) { return this.route('DELETE', path, action, priority); @@ -85,7 +87,7 @@ export default class Router< */ public get( path: string, - action: RouterAction, + action: RouterActions, priority?: number ) { return this.route('GET', path, action, priority); @@ -96,7 +98,7 @@ export default class Router< */ public head( path: string, - action: RouterAction, + action: RouterActions, priority?: number ) { return this.route('HEAD', path, action, priority); @@ -107,7 +109,7 @@ export default class Router< */ public options( path: string, - action: RouterAction, + action: RouterActions, priority?: number ) { return this.route('OPTIONS', path, action, priority); @@ -118,7 +120,7 @@ export default class Router< */ public patch( path: string, - action: RouterAction, + action: RouterActions, priority?: number ) { return this.route('PATCH', path, action, priority); @@ -129,7 +131,7 @@ export default class Router< */ public post( path: string, - action: RouterAction, + action: RouterActions, priority?: number ) { return this.route('POST', path, action, priority); @@ -140,7 +142,7 @@ export default class Router< */ public put( path: string, - action: RouterAction, + action: RouterActions, priority?: number ) { return this.route('PUT', path, action, priority); @@ -151,7 +153,7 @@ export default class Router< */ public trace( path: string, - action: RouterAction, + action: RouterActions, priority?: number ) { return this.route('TRACE', path, action, priority); @@ -163,7 +165,7 @@ export default class Router< public route( method: Method|'[A-Z]+', path: string, - action: RouterAction, + action: RouterActions, priority?: number ) { //convert path to a regex pattern @@ -175,14 +177,27 @@ export default class Router< .replaceAll('*', '([^/]+)') //** -> ([^/]+)([^/]+) -> (.*) .replaceAll('([^/]+)([^/]+)', '(.*)'); + //now form the event pattern const event = new RegExp(`^${method}\\s${pattern}/*$`, 'ig'); this.routes.set(event.toString(), { method: method === '[A-Z]+' ? 'ALL' : method, path: path }); - //add to tasks - return this.on(event, action, priority); + + //delegate to appropriate router based on action type + if (typeof action === 'string') { + //view router for string paths + this.view.on(event, action, priority); + } else if (typeof action === 'function' && action.length === 0) { + //import router for parameterless functions + this.imports.on(event, action as RouterImport, priority); + } else { + //default router for request/response handlers + this.on(event, action as RouterAction, priority); + } + + return this; } /** diff --git a/packages/ingest/src/types.ts b/packages/ingest/src/types.ts index 7f7a236..87bc19d 100644 --- a/packages/ingest/src/types.ts +++ b/packages/ingest/src/types.ts @@ -178,6 +178,12 @@ export type RouterImport = () => Promise<{ default: RouterAction }>; +export type RouterActions< + R = unknown, + S = unknown, + X = unknown +> = string | RouterAction | RouterImport; + export type RouterQueueArgs< R = unknown, S = unknown, diff --git a/packages/ingest/tests/Router.test.ts b/packages/ingest/tests/Router.test.ts index 3bc720c..17b1916 100644 --- a/packages/ingest/tests/Router.test.ts +++ b/packages/ingest/tests/Router.test.ts @@ -7,6 +7,7 @@ import type { RouterImport } from '../src/types'; import Router from '../src/Router'; import Request from '../src/Request'; import Response from '../src/Response'; +import ViewRouter from '../src/router/ViewRouter'; type method = 'all' | 'connect' | 'delete' | 'get' @@ -267,4 +268,45 @@ describe('Router Tests', () => { expect(res.body).to.equal('router1'); }); + + it('Should handle flexible routing types', async () => { + const router = new Router(); + expect(router).to.be.instanceOf(Router); + router.view.engine = function (filePath, req, res) { + res.setBody('text/plain', filePath); + } + // Set up routes with different action types + router.get('/view/path', './templates/view.html'); + router.get('/import/path', () => import('./fixtures/get')); + router.get('/standard/path', (req, res) => { + res.setBody('text/plain', 'standard response'); + }); + + // Test view routing + const viewRequest = new Request({ + method: 'GET', + url: new URL('http://localhost/view/path') + }); + const viewResponse = new Response(); + await router.emit('GET /view/path', viewRequest, viewResponse); + expect(viewResponse.body).to.equal('./templates/view.html'); + + // Test import routing + const importRequest = new Request({ + method: 'GET', + url: new URL('http://localhost/import/path') + }); + const importResponse = new Response(); + await router.emit('GET /import/path', importRequest, importResponse); + expect(importResponse.body).to.equal('/import/path'); + + // Test standard routing + const standardRequest = new Request({ + method: 'GET', + url: new URL('http://localhost/standard/path') + }); + const standardResponse = new Response(); + await router.emit('GET /standard/path', standardRequest, standardResponse); + expect(standardResponse.body).to.equal('standard response'); + }); }) \ No newline at end of file