diff --git a/.gitignore b/.gitignore index d741c9ff..81e37c76 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ dist **/node_modules tsconfig.tsbuildinfo uploads -coverage \ No newline at end of file +coverage +coverage-badges \ No newline at end of file diff --git a/README.md b/README.md index 5f3da52d..f7318ec9 100644 --- a/README.md +++ b/README.md @@ -444,6 +444,9 @@ export default class ProductService extends MedusaProductService { And finally, we need to add the subscriber to the connection. There are different ways to achieve this. We will see, as an example below, a way to attach a request scoped subscribers. +Every middleware decorated with the `@Middleware` decorator will be applied globally on the specified route +before/after medusa authentication. Otherwise, to apply a middleware directly to a route you can have a look to the `@Router` decorator. +
Click to see the example! @@ -594,16 +597,16 @@ npm run start Here is the list of the provided decorators. -| Decorator | Description | Option | -| ---------------------- | ---------------------- | ---------------------- -| `@Entity(/*...*/)` | Decorate an entity | `{ resolutionKey?: string; override?: Type; };` -| `@Repository(/*...*/)` | Decorate a repository | `{ resolutionKey?: string; override?: Type; };` -| `@Service(/*...*/)` | Decorate a service | `{ scope?: LifetimeType; resolutionKey?: string; override?: Type; };` -| `@Middleware(/*...*/)` | Decorate a middleware | `{ requireAuth: boolean; string; routes: MedusaRouteOptions[]; };` -| `@Router(/*...*/)` | Decorate a router | `{ router: RoutesInjectionRouterConfiguration[]; };` -| `@Validator(/*...*/)` | Decorate a validator | `{ override: Type; };` -| `@Migration(/*...*/)` | Decorate a migration | -| `@OnMedusaEntityEvent.\*.\*(/*...*/)`| Can be used to send the right event type or register the handler to an event| `(entity: TEntity, { async? boolean; metatype?: Type })` +| Decorator | Description | Option | +| ---------------------- | ---------------------- | ---------------------- +| `@Entity(/*...*/)` | Decorate an entity | `{ resolutionKey?: string; override?: Type; };` +| `@Repository(/*...*/)` | Decorate a repository | `{ resolutionKey?: string; override?: Type; };` +| `@Service(/*...*/)` | Decorate a service | `{ scope?: LifetimeType; resolutionKey?: string; override?: Type; };` +| `@Middleware(/*...*/)` | Decorate a middleware | `{ requireAuth: boolean; string; routes: MedusaRouteOptions[]; };` +| `@Router(/*...*/)` | Decorate a router, can provide a list of handlers that can include route related middleware| `{ router: RoutesInjectionRouterConfiguration[]; };` +| `@Validator(/*...*/)` | Decorate a validator | `{ override: Type; };` +| `@Migration(/*...*/)` | Decorate a migration | +| `@OnMedusaEntityEvent.\*.\*(/*...*/)`| Can be used to send the right event type or register the handler to an event | `(entity: TEntity, { async? boolean; metatype?: Type })` # Monitoring diff --git a/coverage-bages/badge-branches.svg b/coverage-bages/badge-branches.svg deleted file mode 100644 index 2395c89d..00000000 --- a/coverage-bages/badge-branches.svg +++ /dev/null @@ -1 +0,0 @@ -Coverage:branches: 28.44%Coverage:branches28.44% \ No newline at end of file diff --git a/coverage-bages/badge-functions.svg b/coverage-bages/badge-functions.svg deleted file mode 100644 index b10612d1..00000000 --- a/coverage-bages/badge-functions.svg +++ /dev/null @@ -1 +0,0 @@ -Coverage:functions: 60%Coverage:functions60% \ No newline at end of file diff --git a/coverage-bages/badge-lines.svg b/coverage-bages/badge-lines.svg deleted file mode 100644 index 84e8c351..00000000 --- a/coverage-bages/badge-lines.svg +++ /dev/null @@ -1 +0,0 @@ -Coverage:lines: 70.72%Coverage:lines70.72% \ No newline at end of file diff --git a/coverage-bages/badge-statements.svg b/coverage-bages/badge-statements.svg deleted file mode 100644 index eafd216f..00000000 --- a/coverage-bages/badge-statements.svg +++ /dev/null @@ -1 +0,0 @@ -Coverage:statements: 70.28%Coverage:statements70.28% \ No newline at end of file diff --git a/src/decorators/tests/components.spec.ts b/src/decorators/tests/components.spec.ts index b364bd9a..2e29278b 100644 --- a/src/decorators/tests/components.spec.ts +++ b/src/decorators/tests/components.spec.ts @@ -62,7 +62,7 @@ describe('components', () => { @Router({ routes: [ { - handler: () => '', + handlers: [() => ''], method: 'get', path: '', requiredAuth: true, @@ -78,8 +78,8 @@ describe('components', () => { path: '', requiredAuth: true, }); - expect(metadata.routes[0].handler).toBeDefined(); - expect(metadata.routes[0].handler('')).toEqual(''); + expect(metadata.routes[0].handlers).toBeDefined(); + expect(metadata.routes[0].handlers[0]('')).toEqual(''); }); }); diff --git a/src/loaders/routes.loader.ts b/src/loaders/routes.loader.ts index f7a57870..da62093b 100644 --- a/src/loaders/routes.loader.ts +++ b/src/loaders/routes.loader.ts @@ -2,35 +2,38 @@ import { GetInjectableOptions, MedusaAuthenticatedRequest, RoutesInjectionRouter import { Express, NextFunction, Request, Response } from 'express'; export function authenticatedRoutesLoader(routesOptions: GetInjectableOptions<'router'>, app: Express): void { - for (const routeOptions of routesOptions) { - routeOptions.routes.forEach((route) => { - if (route.requiredAuth) { - registerRoute(app, route); - } - }); - } + for (const routeOptions of routesOptions) { + routeOptions.routes.forEach((route) => { + if (route.requiredAuth) { + registerRoute(app, route); + } + }); + } } export function unauthenticatedRoutesLoader(routesOptions: GetInjectableOptions<'router'>, app: Express): void { - for (const routeOptions of routesOptions) { - routeOptions.routes.forEach((route) => { - if (!route.requiredAuth) { - registerRoute(app, route); - } - }); - } + for (const routeOptions of routesOptions) { + routeOptions.routes.forEach((route) => { + if (!route.requiredAuth) { + registerRoute(app, route); + } + }); + } } function registerRoute(app: Express, route: RoutesInjectionRouterConfiguration): void { - const { method, path, handler } = route; - app[method.toLowerCase()]( - path, - async (req: MedusaAuthenticatedRequest | Request, res: Response, next: NextFunction) => { - try { - return await handler(req, res); - } catch (e) { - return next(e); - } - } - ); + const { method, path, handlers } = route; + app[method.toLowerCase()]( + path, + handlers.map(handler => { + return async (req: MedusaAuthenticatedRequest | Request, res: Response, next: NextFunction) => { + try { + await handler(req, res); + return next(); + } catch (e) { + return next(e); + } + }; + }) + ); } diff --git a/src/types.ts b/src/types.ts index afa36f2e..9e6d58db 100644 --- a/src/types.ts +++ b/src/types.ts @@ -52,7 +52,7 @@ export type RoutesInjectionRouterConfiguration = { requiredAuth: boolean; method: string; path: string; - handler: (...args: unknown[]) => void; + handlers: ((...args: unknown[]) => void)[]; }; /**