Skip to content

Commit

Permalink
adding examples
Browse files Browse the repository at this point in the history
  • Loading branch information
teunmooij committed Jul 15, 2023
1 parent dbc46b1 commit 5299dc7
Show file tree
Hide file tree
Showing 15 changed files with 152 additions and 10 deletions.
4 changes: 4 additions & 0 deletions packages/openapi/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.4.0

- Support for examples of collections and globals

## 1.3.0

- Added detailed documentation of custom endpoints, including summary, description, success and alternative response schemas and query parameters.
Expand Down
56 changes: 56 additions & 0 deletions packages/openapi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,62 @@ Response schemas can be defined as openapi schema objects or as string, referenc

To exclude a custom endpoint from the documentation, set the `custom.openapi` property to `false`.

## Adding examples

Examples can be added on collections and globals.

This can be either a single example:

```ts
import { CollectionConfig } from 'payload/types';

const Categories: CollectionConfig = {
slug: 'categories',
custom: {
openapi: {
example: {
name: 'Example Category',
archived: false,
},
},
},
// ... Rest of collection config
};
```

Or multiple examples

```ts
import { CollectionConfig } from 'payload/types';

const Categories: CollectionConfig = {
slug: 'categories',
custom: {
openapi: {
examples: {
active: {
value: {
name: 'Active Category',
archived: false,
},
summary: 'Example of an active category',
},
archive: {
value: {
name: 'Archived Category',
archived: true,
},
summary: 'Example of an archived category',
},
},
},
},
// ... Rest of collection config
};
```

Openapi supports examples at lots of different levels. To add examples add other levels, you can define theme in a separate partial openapi document, as described [here](#extend-the-openapi-document).

## Excluding unused endpoints

In Payload `collections` and `globals` have a standard set of available endpoints. In some situations you might not want to use some of these endpoints. In those situations you probably have used an access method that looks something like this: `() => false;`. This blocks all traffic, but the endpoint is still part of the openapi documentation.
Expand Down
2 changes: 1 addition & 1 deletion packages/openapi/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "payload-openapi",
"version": "1.3.0",
"version": "1.4.0",
"description": "Create openapi documentation for your payload cms",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
10 changes: 10 additions & 0 deletions packages/openapi/src/config-extensions/examples.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export interface Example<T = any> {
example?: T;
examples?: Record<
string,
{
value: T;
summary?: string;
}
>;
}
2 changes: 2 additions & 0 deletions packages/openapi/src/config-extensions/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export { defineEndpoint, getEndpointDocumentation, EndpointDocumentation } from './custom-endpoint';

export { Example } from './examples';
2 changes: 1 addition & 1 deletion packages/openapi/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ export type { RawOptions as Options } from './options';
export { createDocument };
export default createDocument;

export { defineEndpoint, EndpointDocumentation } from './config-extensions/custom-endpoint';
export { defineEndpoint, EndpointDocumentation, Example } from './config-extensions';
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,11 @@ export const getMainRoutes = async (
};

const { schema, fieldDefinitions } = await entityToSchema(payloadConfig, collection);
const { example, examples } = collection.custom?.openapi || {};

const components: OpenAPIV3.ComponentsObject = {
schemas: {
[schemaName]: schema,
[schemaName]: { ...schema, ...{ example, examples } },
...includeIfAvailable(collection, 'read', {
[pluralSchemaName]: createPaginatedDocumentSchema(schemaName, plural),
}),
Expand Down
3 changes: 2 additions & 1 deletion packages/openapi/src/payload-config/routes/global/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ export const getGlobalRoutes = async (
};

const { schema, fieldDefinitions } = await entityToSchema(payloadConfig, global);
const { example, examples } = global.custom?.openapi || {};

const components: OpenAPIV3.ComponentsObject = {
schemas: {
[schemaName]: schema,
[schemaName]: { ...schema, ...{ example, examples } },
[`${schemaName}UpsertConfirmation`]: createUpsertConfirmationSchema(schemaName, singleItem),
...fieldDefinitions,
},
Expand Down
4 changes: 4 additions & 0 deletions packages/swagger/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.4.0

- Support for examples of collections and globals

## 1.3.1

- Fix issue with import of `defineEndpoint` in webpack
Expand Down
56 changes: 56 additions & 0 deletions packages/swagger/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,62 @@ Response schemas can be defined as openapi schema objects or as string, referenc

To exclude a custom endpoint from the documentation, set the `custom.openapi` property to `false`.

## Adding examples

Examples can be added on collections and globals.

This can be either a single example:

```ts
import { CollectionConfig } from 'payload/types';

const Categories: CollectionConfig = {
slug: 'categories',
custom: {
openapi: {
example: {
name: 'Example Category',
archived: false,
},
},
},
// ... Rest of collection config
};
```

Or multiple examples

```ts
import { CollectionConfig } from 'payload/types';

const Categories: CollectionConfig = {
slug: 'categories',
custom: {
openapi: {
examples: {
active: {
value: {
name: 'Active Category',
archived: false,
},
summary: 'Example of an active category',
},
archive: {
value: {
name: 'Archived Category',
archived: true,
},
summary: 'Example of an archived category',
},
},
},
},
// ... Rest of collection config
};
```

Openapi supports examples at lots of different levels. To add examples add other levels, you can define theme in a separate partial openapi document, as described [here](#extend-the-openapi-document).

## Excluding unused endpoints

In Payload `collections` and `globals` have a standard set of available endpoints. In some situations you might not want to use some of these endpoints. In those situations you probably have used an access method that looks something like this: `() => false;`. This blocks all traffic, but the endpoint is still part of the openapi documentation.
Expand Down
4 changes: 2 additions & 2 deletions packages/swagger/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "payload-swagger",
"version": "1.3.1",
"version": "1.4.0",
"description": "Swagger plugin for payload cms",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand All @@ -13,7 +13,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"payload-openapi": "^1.3.0",
"payload-openapi": "^1.4.0",
"swagger-ui-express": "^4.6.2"
},
"peerDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/swagger/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ export type { Options } from './types';
export { swagger };
export default swagger;

export { defineEndpoint, EndpointDocumentation } from './openapi';
export { defineEndpoint, EndpointDocumentation, Example } from './openapi';
2 changes: 1 addition & 1 deletion packages/swagger/src/openapi.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Endpoint } from 'payload/config';

import type { EndpointDocumentation } from 'payload-openapi';
export type { EndpointDocumentation } from 'payload-openapi';
export type { EndpointDocumentation, Example } from 'payload-openapi';

type DocumentedEndpoint = Endpoint & EndpointDocumentation;

Expand Down
8 changes: 8 additions & 0 deletions packages/testbed/src/collections/Categories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ const Categories: CollectionConfig = {
},
},
],
custom: {
openapi: {
example: {
name: 'Example Category',
archived: false,
},
},
},
};

export default Categories;
4 changes: 2 additions & 2 deletions packages/testbed/src/collections/Posts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ const Posts: CollectionConfig = {
},
},
handler: async (req, res) => {
const { docs } = await req.payload.find<any>({
const { docs } = await req.payload.find({
collection: 'categories',
where: { name: { equals: req.params.category } },
});
Expand All @@ -110,7 +110,7 @@ const Posts: CollectionConfig = {
}

const { limit, page, sort } = req.query;
const posts = await req.payload.find<any>({
const posts = await req.payload.find({
collection: 'posts',
where: { category: { equals: (docs[0] as any).id } },
limit: limit && Number(limit),
Expand Down

0 comments on commit 5299dc7

Please sign in to comment.