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

adds endpoint-specific transforms #752

Merged
merged 5 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from 4 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
49 changes: 36 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ npm i @fastify/swagger
### Compatibility

| Plugin version | Fastify version |
| -------------- |---------------- |
| -------------- | --------------- |
| `^7.0.0` | `^4.0.0` |
| `^6.0.0` | `^3.0.0` |
| `^3.0.0` | `^2.0.0` |
Expand Down Expand Up @@ -219,18 +219,18 @@ An example of using `@fastify/swagger` with `static` mode enabled can be found [

#### Options

| Option | Default | Description |
| ------------------ | ---------------- | -------------------------------------------------------------------------------------------------------------------------- |
| hiddenTag | X-HIDDEN | Tag to control hiding of routes. |
| hideUntagged | false | If `true` remove routes without tags from resulting Swagger/OpenAPI schema file. |
| initOAuth | {} | Configuration options for [Swagger UI initOAuth](https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/). |
| openapi | {} | [OpenAPI configuration](https://swagger.io/specification/#oasObject). |
| stripBasePath | true | Strips base path from routes in docs. |
| swagger | {} | [Swagger configuration](https://swagger.io/specification/v2/#swaggerObject). |
| transform | null | Transform method for the route's schema and url. [documentation](#register.options.transform). | |
| transformObject | null | Transform method for the swagger or openapi object before it is rendered. [documentation](#register.options.transformObject). | |
| refResolver | {} | Option to manage the `$ref`s of your application's schemas. Read the [`$ref` documentation](#register.options.refResolver) |
| exposeHeadRoutes | false | Include HEAD routes in the definitions |
| Option | Default | Description |
| ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------- |
| hiddenTag | X-HIDDEN | Tag to control hiding of routes. |
| hideUntagged | false | If `true` remove routes without tags from resulting Swagger/OpenAPI schema file. |
| initOAuth | {} | Configuration options for [Swagger UI initOAuth](https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/). |
| openapi | {} | [OpenAPI configuration](https://swagger.io/specification/#oasObject). |
| stripBasePath | true | Strips base path from routes in docs. |
| swagger | {} | [Swagger configuration](https://swagger.io/specification/v2/#swaggerObject). |
| transform | null | Transform method for the route's schema and url. [documentation](#register.options.transform). | |
| transformObject | null | Transform method for the swagger or openapi object before it is rendered. [documentation](#register.options.transformObject). | |
| refResolver | {} | Option to manage the `$ref`s of your application's schemas. Read the [`$ref` documentation](#register.options.refResolver) |
| exposeHeadRoutes | false | Include HEAD routes in the definitions |

<a name="register.options.transform"></a>
#### Transform
Expand Down Expand Up @@ -287,6 +287,29 @@ await fastify.register(require('@fastify/swagger'), {
}
})
```

You can also attach the transform function on a specific endpoint:

```js
fastify.get("/", {
schema: { ... },
config: {
swaggerTransform: ({ schema, url, route, swaggerObject }) => { ... }
}
})
```

If both a global and a local transform function is available for an endpoint, the endpoint-specific transform function will be used.

The local transform function can be useful if you:

- want to add additional information to a specific endpoint
- have an endpoint which requires different transformation from other endpoints
- want to entirely ignore the global transform function for one endpoint

The endpoint-specific transform can be used to "disable" the global transform function by passing in `null`.


<a name="register.options.transformObject"></a>
#### Transform Object

Expand Down
26 changes: 19 additions & 7 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,26 @@ declare module 'fastify' {
[statusCode: string]: OpenAPIV3.ResponseObject['links'];
}
}

interface FastifyContextConfig {
swaggerTransform?: SwaggerTransform | null;
}
}

type SwaggerTransform = <S extends FastifySchema = FastifySchema>({
schema,
url,
route,
swaggerObject,
openapiObject,
}: {
schema: S;
url: string;
route: RouteOptions;
swaggerObject: Partial<OpenAPIV2.Document>;
openapiObject: Partial<OpenAPIV3.Document | OpenAPIV3_1.Document>;
}) => { schema: FastifySchema; url: string }

type FastifySwagger = FastifyPluginCallback<fastifySwagger.SwaggerOptions>

declare namespace fastifySwagger {
Expand Down Expand Up @@ -124,13 +142,7 @@ declare namespace fastifySwagger {
/**
* custom function to transform the route's schema and url
*/
transform?: <S extends FastifySchema = FastifySchema>({ schema, url, route, swaggerObject, openapiObject }: {
schema: S,
url: string,
route: RouteOptions,
swaggerObject: Partial<OpenAPIV2.Document>
openapiObject: Partial<OpenAPIV3.Document | OpenAPIV3_1.Document>
}) => { schema: FastifySchema, url: string };
transform?: SwaggerTransform;

/**
* custom function to transform the openapi or swagger object before it is rendered
Expand Down
10 changes: 7 additions & 3 deletions lib/spec/openapi/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@ module.exports = function (opts, cache, routes, Ref, done) {
const serverUrls = resolveServerUrls(defOpts.servers)

for (const route of routes) {
const transformResult = defOpts.transform
? defOpts.transform({ schema: route.schema, url: route.url, route, openapiObject })
: {}
const transformResult = route.config?.swaggerTransform !== undefined
? route.config.swaggerTransform !== null
? route.config.swaggerTransform({ schema: route.schema, url: route.url, route, openapiObject })
: {}
: defOpts.transform
? defOpts.transform({ schema: route.schema, url: route.url, route, openapiObject })
: {}

const schema = transformResult.schema || route.schema
const shouldRouteHideOpts = {
Expand Down
10 changes: 7 additions & 3 deletions lib/spec/swagger/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@ module.exports = function (opts, cache, routes, Ref, done) {

swaggerObject.paths = {}
for (const route of routes) {
const transformResult = defOpts.transform
? defOpts.transform({ schema: route.schema, url: route.url, route, swaggerObject })
: {}
const transformResult = route.config?.swaggerTransform !== undefined
? route.config.swaggerTransform !== null
? route.config.swaggerTransform({ schema: route.schema, url: route.url, route, swaggerObject })
: {}
: defOpts.transform
? defOpts.transform({ schema: route.schema, url: route.url, route, swaggerObject })
: {}

const schema = transformResult.schema || route.schema
const shouldRouteHideOpts = {
Expand Down
Loading