Comparing version 0.1.8 to 0.2.0
import { HandlerContext } from '@netlify/functions'; | ||
import { InternalRouteHandler, RouteHandler, RouteOptions, RouteTree, TreeSearchResult } from './types.js'; | ||
import { InternalRouteHandler, Method, RouteHandler, RouteOptions, RouteTree, TreeSearchResult } from './types.js'; | ||
import { ZodSchema } from 'zod'; | ||
@@ -11,3 +11,3 @@ import { Logger } from './logger.js'; | ||
addRoute<TPath extends string = '', TQuerySchema extends ZodSchema | undefined = undefined, TBodySchema extends ZodSchema | undefined = undefined, TContext extends HandlerContext = HandlerContext>({ method, url, handlers, options, }: { | ||
method: string; | ||
method: Method; | ||
url: TPath; | ||
@@ -17,4 +17,4 @@ handlers: RouteHandler<TPath, TQuerySchema, TBodySchema, TContext>[]; | ||
}): InternalRouteHandler; | ||
recursiveTreeMatch(url: string, fullUrl: string, method: string, tree?: RouteTree): TreeSearchResult | undefined; | ||
recursiveTreeMatch(url: string, fullUrl: string, method: Method, tree?: RouteTree): TreeSearchResult | undefined; | ||
GetAllRoutes(): InternalRouteHandler[]; | ||
} |
@@ -54,3 +54,2 @@ import { withBodyValidator, withQueryValidator } from './middleware.js'; | ||
const route = { | ||
method, | ||
urlPattern: new UrlPattern(routeUrl), | ||
@@ -65,4 +64,7 @@ handlers, | ||
} | ||
if (!this.routeTree.routeHandlers) { | ||
this.routeTree.routeHandlers = {}; | ||
} | ||
if (routeUrl === '/') { | ||
this.routeTree.routeHandler = route; | ||
this.routeTree.routeHandlers[method] = route; | ||
return route; | ||
@@ -82,7 +84,11 @@ } | ||
if (current.children[component]) { | ||
current.children[component].routeHandler = route; | ||
const currentChild = current.children[component]; | ||
if (!currentChild.routeHandlers) { | ||
currentChild.routeHandlers = {}; | ||
} | ||
currentChild.routeHandlers[method] = route; | ||
} | ||
else { | ||
current.children[component] = { | ||
routeHandler: route, | ||
routeHandlers: { [method]: route }, | ||
}; | ||
@@ -103,9 +109,9 @@ } | ||
if (url === '/') { | ||
if (tree.routeHandler) { | ||
if (tree.routeHandler.method === method && | ||
tree.routeHandler.urlPattern.match(fullUrl)) { | ||
if (tree.routeHandlers) { | ||
const potentialMatch = tree.routeHandlers[method]; | ||
if (potentialMatch && potentialMatch.urlPattern.match(fullUrl)) { | ||
return { | ||
matchedRoute: tree.routeHandler, | ||
params: tree.routeHandler.urlPattern.parse(fullUrl), | ||
handlers: tree.routeHandler.handlers, | ||
matchedRoute: potentialMatch, | ||
params: potentialMatch.urlPattern.parse(fullUrl), | ||
handlers: potentialMatch.handlers, | ||
}; | ||
@@ -120,14 +126,14 @@ } | ||
// If we're at the end of the URL, return the handlers | ||
if (node.routeHandler) { | ||
if (node.routeHandlers) { | ||
this.logger.debug(`Node is a route handler for ${current}`); | ||
if (rest.length === 0) { | ||
if (node.routeHandler.method === method && | ||
node.routeHandler.urlPattern.match(fullUrl)) { | ||
const potentialMatch = node.routeHandlers[method]; | ||
if (potentialMatch && potentialMatch.urlPattern.match(fullUrl)) { | ||
return { | ||
matchedRoute: node.routeHandler, | ||
params: node.routeHandler.urlPattern.parse(fullUrl), | ||
matchedRoute: potentialMatch, | ||
params: potentialMatch.urlPattern.parse(fullUrl), | ||
handlers: [ | ||
...(tree.middleware ?? []), | ||
...(node.middleware ?? []), | ||
...node.routeHandler.handlers, | ||
...potentialMatch.handlers, | ||
].filter(Boolean), | ||
@@ -164,17 +170,20 @@ }; | ||
this.logger.debug(`Trying argument node ${argumentNode}...`); | ||
if (argumentNode.routeHandler) { | ||
if (argumentNode.routeHandlers) { | ||
this.logger.debug(`Node is a route handler for ${current}`); | ||
const potentialMatch = argumentNode.routeHandlers[method]; | ||
if (rest.length === 0) { | ||
if (argumentNode.routeHandler.method === method && | ||
argumentNode.routeHandler.urlPattern.match(fullUrl)) { | ||
if (potentialMatch && potentialMatch.urlPattern.match(fullUrl)) { | ||
return { | ||
matchedRoute: argumentNode.routeHandler, | ||
params: argumentNode.routeHandler.urlPattern.parse(fullUrl), | ||
matchedRoute: potentialMatch, | ||
params: potentialMatch.urlPattern.parse(fullUrl), | ||
handlers: [ | ||
...(tree.middleware ?? []), | ||
...(argumentNode.middleware ?? []), | ||
...argumentNode.routeHandler.handlers, | ||
...potentialMatch.handlers, | ||
].filter(Boolean), | ||
}; | ||
} | ||
else { | ||
this.logger.debug(`Method or URL pattern did not match for ${current}`); | ||
} | ||
} | ||
@@ -205,4 +214,4 @@ } | ||
const recurse = (tree) => { | ||
if (tree.routeHandler) { | ||
routes.push(tree.routeHandler); | ||
if (tree.routeHandlers) { | ||
routes.push(...Object.values(tree.routeHandlers)); | ||
} | ||
@@ -209,0 +218,0 @@ if (tree.children) { |
@@ -35,9 +35,9 @@ import { ZodSchema, z } from 'zod'; | ||
export interface InternalRouteHandler { | ||
method: string; | ||
urlPattern: UrlPattern; | ||
handlers: any[]; | ||
} | ||
export type Method = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'; | ||
export interface RouteTree { | ||
middleware?: RouteHandler[]; | ||
routeHandler?: InternalRouteHandler; | ||
routeHandlers?: Partial<Record<Method, InternalRouteHandler>>; | ||
children?: { | ||
@@ -44,0 +44,0 @@ [key: string]: RouteTree; |
{ | ||
"name": "funclify", | ||
"version": "0.1.8", | ||
"version": "0.2.0", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -10,2 +10,3 @@ import { | ||
import { | ||
Method, | ||
RouteContext, | ||
@@ -268,3 +269,3 @@ RouteHandler, | ||
} | ||
const method = event.httpMethod; | ||
const method = event.httpMethod as Method; | ||
@@ -271,0 +272,0 @@ let components = url.split('/'); |
@@ -5,2 +5,3 @@ import { HandlerContext } from '@netlify/functions'; | ||
InternalRouteHandler, | ||
Method, | ||
RouteHandler, | ||
@@ -80,3 +81,3 @@ RouteOptions, | ||
}: { | ||
method: string; | ||
method: Method; | ||
url: TPath; | ||
@@ -91,3 +92,2 @@ handlers: RouteHandler<TPath, TQuerySchema, TBodySchema, TContext>[]; | ||
const route: InternalRouteHandler = { | ||
method, | ||
urlPattern: new UrlPattern(routeUrl), | ||
@@ -104,4 +104,8 @@ handlers, | ||
if (!this.routeTree.routeHandlers) { | ||
this.routeTree.routeHandlers = {}; | ||
} | ||
if (routeUrl === '/') { | ||
this.routeTree.routeHandler = route; | ||
this.routeTree.routeHandlers[method] = route; | ||
return route; | ||
@@ -125,6 +129,10 @@ } | ||
if (current.children[component]) { | ||
current.children[component].routeHandler = route; | ||
const currentChild = current.children[component]; | ||
if (!currentChild.routeHandlers) { | ||
currentChild.routeHandlers = {}; | ||
} | ||
currentChild.routeHandlers[method] = route; | ||
} else { | ||
current.children[component] = { | ||
routeHandler: route, | ||
routeHandlers: { [method]: route }, | ||
}; | ||
@@ -148,3 +156,3 @@ } | ||
fullUrl: string, | ||
method: string, | ||
method: Method, | ||
tree: RouteTree = this.routeTree | ||
@@ -156,11 +164,9 @@ ): TreeSearchResult | undefined { | ||
if (url === '/') { | ||
if (tree.routeHandler) { | ||
if ( | ||
tree.routeHandler.method === method && | ||
tree.routeHandler.urlPattern.match(fullUrl) | ||
) { | ||
if (tree.routeHandlers) { | ||
const potentialMatch = tree.routeHandlers[method]; | ||
if (potentialMatch && potentialMatch.urlPattern.match(fullUrl)) { | ||
return { | ||
matchedRoute: tree.routeHandler, | ||
params: tree.routeHandler.urlPattern.parse(fullUrl), | ||
handlers: tree.routeHandler.handlers, | ||
matchedRoute: potentialMatch, | ||
params: potentialMatch.urlPattern.parse(fullUrl), | ||
handlers: potentialMatch.handlers, | ||
}; | ||
@@ -176,16 +182,14 @@ } | ||
// If we're at the end of the URL, return the handlers | ||
if (node.routeHandler) { | ||
if (node.routeHandlers) { | ||
this.logger.debug(`Node is a route handler for ${current}`); | ||
if (rest.length === 0) { | ||
if ( | ||
node.routeHandler.method === method && | ||
node.routeHandler.urlPattern.match(fullUrl) | ||
) { | ||
const potentialMatch = node.routeHandlers[method]; | ||
if (potentialMatch && potentialMatch.urlPattern.match(fullUrl)) { | ||
return { | ||
matchedRoute: node.routeHandler, | ||
params: node.routeHandler.urlPattern.parse(fullUrl), | ||
matchedRoute: potentialMatch, | ||
params: potentialMatch.urlPattern.parse(fullUrl), | ||
handlers: [ | ||
...(tree.middleware ?? []), | ||
...(node.middleware ?? []), | ||
...node.routeHandler.handlers, | ||
...potentialMatch.handlers, | ||
].filter(Boolean), | ||
@@ -235,18 +239,20 @@ }; | ||
this.logger.debug(`Trying argument node ${argumentNode}...`); | ||
if (argumentNode.routeHandler) { | ||
if (argumentNode.routeHandlers) { | ||
this.logger.debug(`Node is a route handler for ${current}`); | ||
const potentialMatch = argumentNode.routeHandlers[method]; | ||
if (rest.length === 0) { | ||
if ( | ||
argumentNode.routeHandler.method === method && | ||
argumentNode.routeHandler.urlPattern.match(fullUrl) | ||
) { | ||
if (potentialMatch && potentialMatch.urlPattern.match(fullUrl)) { | ||
return { | ||
matchedRoute: argumentNode.routeHandler, | ||
params: argumentNode.routeHandler.urlPattern.parse(fullUrl), | ||
matchedRoute: potentialMatch, | ||
params: potentialMatch.urlPattern.parse(fullUrl), | ||
handlers: [ | ||
...(tree.middleware ?? []), | ||
...(argumentNode.middleware ?? []), | ||
...argumentNode.routeHandler.handlers, | ||
...potentialMatch.handlers, | ||
].filter(Boolean), | ||
}; | ||
} else { | ||
this.logger.debug( | ||
`Method or URL pattern did not match for ${current}` | ||
); | ||
} | ||
@@ -290,4 +296,4 @@ } | ||
const recurse = (tree: RouteTree) => { | ||
if (tree.routeHandler) { | ||
routes.push(tree.routeHandler); | ||
if (tree.routeHandlers) { | ||
routes.push(...Object.values(tree.routeHandlers)); | ||
} | ||
@@ -294,0 +300,0 @@ |
@@ -88,3 +88,2 @@ import { ZodSchema, z } from 'zod'; | ||
export interface InternalRouteHandler { | ||
method: string; | ||
urlPattern: UrlPattern; | ||
@@ -94,5 +93,14 @@ handlers: any[]; | ||
export type Method = | ||
| 'GET' | ||
| 'POST' | ||
| 'PUT' | ||
| 'PATCH' | ||
| 'DELETE' | ||
| 'HEAD' | ||
| 'OPTIONS'; | ||
export interface RouteTree { | ||
middleware?: RouteHandler[]; | ||
routeHandler?: InternalRouteHandler; | ||
routeHandlers?: Partial<Record<Method, InternalRouteHandler>>; | ||
children?: { | ||
@@ -99,0 +107,0 @@ [key: string]: RouteTree; |
81558
2067