@hyperspan/framework 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperspan/framework",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Hyperspan Web Framework",
5
5
  "main": "src/server.ts",
6
6
  "types": "src/server.ts",
@@ -67,6 +67,34 @@ test('server returns a route with a POST request', async () => {
67
67
  expect(await response.text()).toBe('<h1>POST /users</h1>');
68
68
  });
69
69
 
70
+ test('server returns a route with a ALL request', async () => {
71
+ const server = await createServer({
72
+ appDir: './app',
73
+ publicDir: './public',
74
+ plugins: [],
75
+ });
76
+
77
+ server.all('/users', (context: HS.Context) => {
78
+ return context.res.html('<h1>ALL /users</h1>');
79
+ });
80
+
81
+ const route = server._routes.find((route: HS.Route) => route._path() === '/users' && route._methods().includes('*')) as HS.Route;
82
+
83
+ // GET request
84
+ let request = new Request('http://localhost:3000/users', { method: 'GET' });
85
+ let response = await route.fetch(request);
86
+ expect(response).toBeInstanceOf(Response);
87
+ expect(response.status).toBe(200);
88
+ expect(await response.text()).toBe('<h1>ALL /users</h1>');
89
+
90
+ // POST request
91
+ request = new Request('http://localhost:3000/users', { method: 'POST' });
92
+ response = await route.fetch(request);
93
+ expect(response).toBeInstanceOf(Response);
94
+ expect(response.status).toBe(200);
95
+ expect(await response.text()).toBe('<h1>ALL /users</h1>');
96
+ });
97
+
70
98
  test('returns 405 when route path matches but HTTP method does not', async () => {
71
99
  const server = await createServer({
72
100
  appDir: './app',
package/src/server.ts CHANGED
@@ -184,6 +184,14 @@ export function createRoute(config: Partial<HS.RouteConfig> = {}): HS.Route {
184
184
  _middleware['OPTIONS'] = handlerOptions?.middleware || [];
185
185
  return api;
186
186
  },
187
+ /**
188
+ * Add a ALL route handler (typically to handle all HTTP methods)
189
+ */
190
+ all(handler: HS.RouteHandler, handlerOptions?: HS.RouteHandlerOptions) {
191
+ _handlers['*'] = handler;
192
+ _middleware['*'] = handlerOptions?.middleware || [];
193
+ return api;
194
+ },
187
195
  /**
188
196
  * Set a custom error handler for this route to fall back to if the route handler throws an error
189
197
  */
@@ -192,7 +200,15 @@ export function createRoute(config: Partial<HS.RouteConfig> = {}): HS.Route {
192
200
  return api;
193
201
  },
194
202
  /**
195
- * Add middleware specific to this route
203
+ * Add a middleware function to this route (for all HTTP methods) (non-destructive)
204
+ */
205
+ use(middleware: HS.MiddlewareFunction) {
206
+ _middleware['*'].push(middleware);
207
+ return api;
208
+ },
209
+ /**
210
+ * Set the complete middleware stack for this route (for all HTTP methods) (destructive)
211
+ * NOTE: This will override the middleware stack for this route
196
212
  */
197
213
  middleware(middleware: Array<HS.MiddlewareFunction>) {
198
214
  _middleware['*'] = middleware;
@@ -231,7 +247,7 @@ export function createRoute(config: Partial<HS.RouteConfig> = {}): HS.Route {
231
247
  );
232
248
  }
233
249
 
234
- const handler = method === 'HEAD' ? _handlers['GET'] : _handlers[method];
250
+ const handler = (method === 'HEAD' ? _handlers['GET'] : _handlers[method]) ?? _handlers['*'];
235
251
 
236
252
  if (!handler) {
237
253
  return context.res.error(new Error('Method not allowed'), { status: 405 });
@@ -332,6 +348,12 @@ export async function createServer(config: HS.Config = {} as HS.Config): Promise
332
348
  _routes.push(route);
333
349
  return route;
334
350
  },
351
+ all(path: string, handler: HS.RouteHandler, handlerOptions?: HS.RouteHandlerOptions) {
352
+ const route = createRoute().all(handler, handlerOptions);
353
+ route._config.path = path;
354
+ _routes.push(route);
355
+ return route;
356
+ },
335
357
  };
336
358
 
337
359
  return api;
package/src/types.ts CHANGED
@@ -16,6 +16,7 @@ export namespace Hyperspan {
16
16
  patch: (path: string, handler: Hyperspan.RouteHandler, handlerOptions?: Hyperspan.RouteHandlerOptions) => Hyperspan.Route;
17
17
  delete: (path: string, handler: Hyperspan.RouteHandler, handlerOptions?: Hyperspan.RouteHandlerOptions) => Hyperspan.Route;
18
18
  options: (path: string, handler: Hyperspan.RouteHandler, handlerOptions?: Hyperspan.RouteHandlerOptions) => Hyperspan.Route;
19
+ all: (path: string, handler: Hyperspan.RouteHandler, handlerOptions?: Hyperspan.RouteHandlerOptions) => Hyperspan.Route;
19
20
  };
20
21
 
21
22
  export type Plugin = (config: Hyperspan.Config) => Promise<void> | void;
@@ -145,7 +146,9 @@ export namespace Hyperspan {
145
146
  patch: (handler: Hyperspan.RouteHandler, handlerOptions?: Hyperspan.RouteHandlerOptions) => Hyperspan.Route;
146
147
  delete: (handler: Hyperspan.RouteHandler, handlerOptions?: Hyperspan.RouteHandlerOptions) => Hyperspan.Route;
147
148
  options: (handler: Hyperspan.RouteHandler, handlerOptions?: Hyperspan.RouteHandlerOptions) => Hyperspan.Route;
149
+ all: (handler: Hyperspan.RouteHandler, handlerOptions?: Hyperspan.RouteHandlerOptions) => Hyperspan.Route;
148
150
  errorHandler: (handler: Hyperspan.ErrorHandler) => Hyperspan.Route;
151
+ use: (middleware: Hyperspan.MiddlewareFunction) => Hyperspan.Route;
149
152
  middleware: (middleware: Array<Hyperspan.MiddlewareFunction>) => Hyperspan.Route;
150
153
  fetch: (request: Request) => Promise<Response>;
151
154
  };