Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

transformRouteOptions plugin option #96

Merged
merged 4 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,13 @@ app.register(require('fastify-overview'), {
exposeRouteOptions: {
method: 'POST', // default: 'GET'
url: '/customUrl', // default: '/json-overview'
},
transformRouteOptions: (opts) => {
Eomm marked this conversation as resolved.
Show resolved Hide resolved
return {
method: opts.method,
url: opts.url,
schema: opts.schema
}
}
})

Expand Down Expand Up @@ -294,6 +301,23 @@ 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

This option can be used to determine which properties of the route options are 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:
```js
transformRouteOptions: (routeOptions) => {
return {
method: routeOptions.method,
url: routeOptions.url,
prefix: routeOptions.prefix
}
}
```

## License

Copyright [Manuel Spigolon](https://github.com/Eomm), Licensed under [MIT](./LICENSE).
13 changes: 9 additions & 4 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,18 @@ interface RouteItem {
source?: OverviewStructureSource,
}

export interface OverviewStructure {
export interface OverviewStructure<T = RouteItem> {
id: Number,
name: string,
source?: OverviewStructureSource,
children?: OverviewStructure[],
children?: OverviewStructure<T>[],
decorators?: {
decorate: OverviewStructureDecorator[],
decorateRequest: OverviewStructureDecorator[],
decorateReply: OverviewStructureDecorator[]
},
hooks?: OverviewStructureHooks,
routes?: RouteItem[]
routes?: (T & { hooks: OverviewStructureHooks, source?: OverviewStructureSource }) []
}

export interface FastifyOverviewOptions {
Expand All @@ -82,6 +82,11 @@ export interface FastifyOverviewOptions {
* Customize the route's options when `exposeRoute` is set to `true`
*/
exposeRouteOptions?: Partial<RouteOptions>,

/**
* Customise which properties of the route options will be included in the overview
*/
transformRouteOptions?: (routeOptions: RouteOptions & { routePath: string; path: string; prefix: string }) => Record<string, unknown>
}

export interface FastifyOverviewDecoratorOptions {
Expand All @@ -98,7 +103,7 @@ export interface FastifyOverviewDecoratorOptions {

declare module 'fastify' {
export interface FastifyInstance {
overview: (opts?: FastifyOverviewDecoratorOptions) => OverviewStructure;
overview: <T = RouteItem>(opts?: FastifyOverviewDecoratorOptions) => OverviewStructure<T>;
}
}

Expand Down
11 changes: 9 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@ const {

function fastifyOverview (fastify, options, next) {
const opts = Object.assign({
addSource: false
addSource: false,
transformRouteOptions: (routeOptions) => {
return {
method: routeOptions.method,
url: routeOptions.url,
prefix: routeOptions.prefix
}
}
}, options)

const contextMap = new Map()
Expand All @@ -31,7 +38,7 @@ function fastifyOverview (fastify, options, next) {
})

fastify.addHook('onRoute', function markRoute (routeOpts) {
const routeNode = transformRoute(routeOpts)
const routeNode = transformRoute(routeOpts, opts.transformRouteOptions)
Eomm marked this conversation as resolved.
Show resolved Hide resolved
if (opts.addSource) {
routeNode.source = routeOpts.handler[kSourceRoute]

Expand Down
7 changes: 2 additions & 5 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ function getFunctionName (func) {
}
}

function transformRoute (routeOpts) {
function transformRoute (routeOpts, transformRouteOptions) {
Eomm marked this conversation as resolved.
Show resolved Hide resolved
const hooks = getEmptyHookRoute()

for (const hook of Object.keys(hooks)) {
if (routeOpts[hook]) {
if (Array.isArray(routeOpts[hook])) {
Expand All @@ -35,9 +34,7 @@ function transformRoute (routeOpts) {
}

return {
method: routeOpts.method,
url: routeOpts.url,
prefix: routeOpts.prefix,
...transformRouteOptions(routeOpts),
hooks
}
}
Expand Down
42 changes: 42 additions & 0 deletions test/fixture/routes.04.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
[
{
"method": "GET",
"url":"/get",
"prefix":"",
"bodySchema": null,
"hooks":{
"onRequest":[ ],
"preParsing":[ ],
"preValidation":[ ],
"preHandler":[ ],
"preSerialization":[ ],
"onError":[ ],
"onSend":[ ],
"onResponse":[ ],
"onTimeout":[ ],
"onRequestAbort":[ ]
}
},
{
"method": "POST",
"url":"/post",
"prefix":"",
"bodySchema": {
"test": {
"type": "string"
}
},
"hooks":{
"onRequest":[ ],
"preParsing":[ ],
"preValidation":[ ],
"preHandler":[ ],
"preSerialization":[ ],
"onError":[ ],
"onSend":[ ],
"onResponse":[ ],
"onTimeout":[ ],
"onRequestAbort":[ ]
}
}
]
20 changes: 20 additions & 0 deletions test/fixture/routes.05.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[
{
"method": "PUT",
"url":"/api/plugin",
"prefix":"/api",
"bodySchema": null,
"hooks":{
"onRequest":[ ],
"preParsing":[ ],
"preValidation":[ ],
"preHandler":[ ],
"preSerialization":[ ],
"onError":[ ],
"onSend":[ ],
"onResponse":[ ],
"onTimeout":[ ],
"onRequestAbort":[ ]
}
}
]
24 changes: 24 additions & 0 deletions test/fixture/routes.06.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[
{
"method": "PATCH",
"url":"/api/patch/:param",
"prefix":"/api",
"bodySchema": {
"text": {
"type": "boolean"
}
},
"hooks":{
"onRequest":[ ],
"preParsing":[ ],
"preValidation":[ ],
"preHandler":[ ],
"preSerialization":[ ],
"onError":[ ],
"onSend":[ ],
"onResponse":[ ],
"onTimeout":[ ],
"onRequestAbort":[ ]
}
}
]
55 changes: 55 additions & 0 deletions test/routes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,58 @@ test('routes', async t => {
t.same(reg3.routes.length, 9)
t.same(reg3.routes, require('./fixture/routes.03.json'))
})

test('custom transformRouteOptions', async t => {
const app = fastify({ exposeHeadRoutes: false })

await app.register(plugin, {
transformRouteOptions: (opts) => {
return {
url: opts.url,
prefix: opts.prefix,
method: opts.method,
bodySchema: opts.schema ? opts.schema.body : undefined
}
}
})

app.get('/get', noop)
app.post('/post', { schema: { body: { test: { type: 'string' } } } }, noop)

app.register(async (instance) => {
instance.put('/plugin', { schema: { querystring: { size: { type: 'integer' } } } }, noop)

instance.register(async function (instance2) {
instance2.patch('/patch/:param', {
schema: {
params: {
param: {
type: 'string'
}
},
body: {
text: {
type: 'boolean'
}
}
}
}, noop)
})
}, { prefix: 'api' })

await app.ready()

const root = app.overview()

t.equal(root.children.length, 1)
t.equal(root.routes.length, 2)
t.same(root.routes, require('./fixture/routes.04.json'))

t.equal(root.children[0].routes.length, 1)
t.equal(root.children[0].children.length, 1)
t.same(root.children[0].routes, require('./fixture/routes.05.json'))

t.equal(root.children[0].children[0].routes.length, 1)
t.equal(root.children[0].children[0].children.length, 0)
t.same(root.children[0].children[0].routes, require('./fixture/routes.06.json'))
})
18 changes: 17 additions & 1 deletion test/types/index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { expectType } from 'tsd'
import { expectError, expectType } from 'tsd'

import fastify from 'fastify'
import fastifyOverview, { OverviewStructure } from '../../index'
Expand All @@ -18,3 +18,19 @@ app
expectType<OverviewStructure>(data)
})
.ready()

app
.register(fastifyOverview, {
transformRouteOptions: (routeOptions) => {
return {
bodySchema: routeOptions.schema?.body,
headerNames: Object.keys(routeOptions.schema?.headers ?? {})
}
}
})
.after((_) => {
const data = app.overview<{ bodySchema: {}, headerNames: string[] }>()
expectType<OverviewStructure<{ bodySchema: {}, headerNames: string[] }>>(data)
expectError<OverviewStructure>(data)
})
.ready()
Loading