diff --git a/README.md b/README.md index 0a42d2a..f9b2e62 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Doing so you will get a complete overview of your application and you can: - optimize your code - optimize your application structure -- find out the application structure (expecially if you have joined a new team) +- find out the application structure (especially if you have joined a new team) - automate some documentation tasks This plugin is intended to be run only for _development_ purposes. @@ -176,11 +176,9 @@ app.register(require('fastify-overview'), { exposeRouteOptions: { method: 'POST', // default: 'GET' url: '/customUrl', // default: '/json-overview' - }, - transformRouteOptions: (opts) => { + }, + onRouteDefinition: (opts) => { return { - method: opts.method, - url: opts.url, schema: opts.schema } } @@ -301,22 +299,24 @@ By default the route is exposed at `GET /json-overview`. You can customize the route's options when `exposeRoute` is set to `true`. You can provide all the [fastify route's options](https://www.fastify.io/docs/latest/Reference/Routes/#routes-options) except the `handler`. -### transformRouteOptions +### onRouteDefinition -This option can be used to determine which properties of the route options are included in the overview. +This option can be used to determine which properties of the route options are additional included in the overview. The function receives the [RouteOptions](https://github.com/fastify/fastify/blob/62f564d965949bc123184a27a610f214f23e9a49/types/hooks.d.ts#L695) -object as the only parameter and must return an object with the desired properties. -The hooks and, depending on the [configuration](#addsource), the source are then also appended to the final object. -The default value if no function is given is: +object as the only parameter and must return an object with the desired properties. You can also overwrite the properties +that are included in the route overview by default (namely `url`, `method`, `prefix` and `hooks`). You cannot +override the `source` property. ```js - transformRouteOptions: (routeOptions) => { + onRouteDefinition: (routeOptions) => { return { method: routeOptions.method, - url: routeOptions.url, - prefix: routeOptions.prefix + url: routeOptions.url.length, + prefix: routeOptions.prefix, + schema: routeOptions.schema } } ``` +In this example, the `url` property is overridden and the `url` length is returned instead of the `url`. ## License diff --git a/index.d.ts b/index.d.ts index 489d3c4..c85cb1d 100644 --- a/index.d.ts +++ b/index.d.ts @@ -50,7 +50,7 @@ interface RouteItem { source?: OverviewStructureSource, } -export interface OverviewStructure { +export interface OverviewStructure { id: Number, name: string, source?: OverviewStructureSource, @@ -61,7 +61,7 @@ export interface OverviewStructure { decorateReply: OverviewStructureDecorator[] }, hooks?: OverviewStructureHooks, - routes?: (T & { hooks: OverviewStructureHooks, source?: OverviewStructureSource }) [] + routes?: (Omit & T)[] } export interface FastifyOverviewOptions { @@ -86,7 +86,7 @@ export interface FastifyOverviewOptions { /** * Customise which properties of the route options will be included in the overview */ - transformRouteOptions?: (routeOptions: RouteOptions & { routePath: string; path: string; prefix: string }) => Record + onRouteDefinition?: (routeOptions: RouteOptions & { routePath: string; path: string; prefix: string }) => Record } export interface FastifyOverviewDecoratorOptions { @@ -103,7 +103,7 @@ export interface FastifyOverviewDecoratorOptions { declare module 'fastify' { export interface FastifyInstance { - overview: (opts?: FastifyOverviewDecoratorOptions) => OverviewStructure; + overview: (opts?: FastifyOverviewDecoratorOptions) => OverviewStructure; } } diff --git a/index.js b/index.js index 5e64bf2..536aab1 100644 --- a/index.js +++ b/index.js @@ -18,14 +18,7 @@ const { function fastifyOverview (fastify, options, next) { const opts = Object.assign({ - addSource: false, - transformRouteOptions: (routeOptions) => { - return { - method: routeOptions.method, - url: routeOptions.url, - prefix: routeOptions.prefix - } - } + addSource: false }, options) const contextMap = new Map() @@ -38,7 +31,7 @@ function fastifyOverview (fastify, options, next) { }) fastify.addHook('onRoute', function markRoute (routeOpts) { - const routeNode = transformRoute(routeOpts, opts.transformRouteOptions) + const routeNode = Object.assign(transformRoute(routeOpts), opts.onRouteDefinition?.(routeOpts)) if (opts.addSource) { routeNode.source = routeOpts.handler[kSourceRoute] diff --git a/lib/utils.js b/lib/utils.js index ad88523..b42473b 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -21,7 +21,7 @@ function getFunctionName (func) { } } -function transformRoute (routeOpts, transformRouteOptions) { +function transformRoute (routeOpts) { const hooks = getEmptyHookRoute() for (const hook of Object.keys(hooks)) { if (routeOpts[hook]) { @@ -34,7 +34,9 @@ function transformRoute (routeOpts, transformRouteOptions) { } return { - ...transformRouteOptions(routeOpts), + method: routeOpts.method, + url: routeOpts.url, + prefix: routeOpts.prefix, hooks } } diff --git a/test/fixture/routes.07.json b/test/fixture/routes.07.json new file mode 100644 index 0000000..8f67a3c --- /dev/null +++ b/test/fixture/routes.07.json @@ -0,0 +1,36 @@ +[ + { + "method": "GETGET", + "url":"static url", + "prefix":"", + "hooks":{ + "onRequest":[ ], + "preParsing":[ ], + "preValidation":[ ], + "preHandler":[ ], + "preSerialization":[ ], + "onError":[ ], + "onSend":[ ], + "onResponse":[ ], + "onTimeout":[ ], + "onRequestAbort":[ ] + } + }, + { + "method": "POSTPOST", + "url":"static url", + "prefix":"", + "hooks":{ + "onRequest":[ ], + "preParsing":[ ], + "preValidation":[ ], + "preHandler":[ ], + "preSerialization":[ ], + "onError":[ ], + "onSend":[ ], + "onResponse":[ ], + "onTimeout":[ ], + "onRequestAbort":[ ] + } + } +] diff --git a/test/routes.test.js b/test/routes.test.js index accfc55..3d7b65c 100644 --- a/test/routes.test.js +++ b/test/routes.test.js @@ -94,15 +94,12 @@ test('routes', async t => { t.same(reg3.routes, require('./fixture/routes.03.json')) }) -test('custom transformRouteOptions', async t => { +test('custom onRouteDefinition', async t => { const app = fastify({ exposeHeadRoutes: false }) await app.register(plugin, { - transformRouteOptions: (opts) => { + onRouteDefinition: (opts) => { return { - url: opts.url, - prefix: opts.prefix, - method: opts.method, bodySchema: opts.schema ? opts.schema.body : undefined } } @@ -148,3 +145,27 @@ test('custom transformRouteOptions', async t => { t.equal(root.children[0].children[0].children.length, 0) t.same(root.children[0].children[0].routes, require('./fixture/routes.06.json')) }) + +test('custom onRouteDefinition with overriding', async t => { + const app = fastify({ exposeHeadRoutes: false }) + + await app.register(plugin, { + onRouteDefinition: (opts) => { + return { + url: 'static url', + method: opts.method + opts.method + } + } + }) + + app.get('/get', noop) + app.post('/post', { schema: { body: { test: { type: 'string' } } } }, noop) + + await app.ready() + + const root = app.overview() + + t.equal(root.children.length, 0) + t.equal(root.routes.length, 2) + t.same(root.routes, require('./fixture/routes.07.json')) +}) diff --git a/test/types/index.test-d.ts b/test/types/index.test-d.ts index 9c8e2f9..bf2c00b 100644 --- a/test/types/index.test-d.ts +++ b/test/types/index.test-d.ts @@ -21,7 +21,7 @@ app app .register(fastifyOverview, { - transformRouteOptions: (routeOptions) => { + onRouteDefinition: (routeOptions) => { return { bodySchema: routeOptions.schema?.body, headerNames: Object.keys(routeOptions.schema?.headers ?? {}) @@ -31,6 +31,20 @@ app .after((_) => { const data = app.overview<{ bodySchema: {}, headerNames: string[] }>() expectType>(data) - expectError(data) + }) + .ready() + +app + .register(fastifyOverview, { + onRouteDefinition: (routeOptions) => { + return { + url: routeOptions.url.length + } + } + }) + .after((_) => { + const data = app.overview<{ url: number }>() + expectType>(data) + expectType(data.routes![0].url) }) .ready()