Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion custom-plugin-decorators/azure-apim/azure-apim.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
export default function plugin() {
id: "azure-apim",
decorators: {
oas3: {
Expand Down
2 changes: 1 addition & 1 deletion custom-plugin-decorators/openai-is-consequential/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ If you want to set the GET operations to true too, then this decorator is for yo
The code is entirely in `openai-is-consequential.js`:

```javascript
module.exports = {
export default function plugin() {
id: "openai-plugin",
decorators: {
oas3: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
export default function plugin() {
id: "openai-plugin",
decorators: {
oas3: {
Expand Down
17 changes: 9 additions & 8 deletions custom-plugin-decorators/remove-extensions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ The plugin itself can be found in [`remove-extensions.js'](./remove-extensions.j
Create a `plugin.js` file to refer to this file:

```js
const RemoveExtensions = require("./remove-extensions");
const id = "plugin";
import RemoveExtensions from "./remove-extensions";

/** @type {import('@redocly/cli').DecoratorsConfig} */
const decorators = {
Expand All @@ -27,10 +26,12 @@ const decorators = {
},
};

module.exports = {
id,
decorators,
};
export default function plugin() {
return {
id: "plugin",
decorators,
};
}
```

Create/edit `redocly.yaml` as follows (edit with your own settings):
Expand All @@ -47,14 +48,15 @@ apis:
- x-amazon*
- x-google*
plugins:
- "./plugin.js"
- ./plugin.js
```

Run the `bundle` command to remove all the [GCP](https://cloud.google.com/endpoints/docs/openapi/openapi-extensions) and [AWS](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions.html) custom OpenAPI extensions from the OpenAPI description:

```bash
redocly bundle with-plugin@latest --output dist/with-plugin.yaml
```

The `extensions` parameter is optional. If empty or not set, it will remove all extensions (elements starting with `x-`). The accepted values for the `extensions` param are:

- `extensions: <regex-valid-extension>`
Expand All @@ -63,7 +65,6 @@ The `extensions` parameter is optional. If empty or not set, it will remove all

Regular expressions follow [Javascript Regex convention](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions).


## Examples

With the same config as above.
Expand Down
107 changes: 62 additions & 45 deletions custom-plugin-decorators/remove-extensions/remove-extensions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
module.exports = RemoveExtensions;

/** @type {import('@redocly/cli').OasDecorator} */

const openAPIExtensions = /x-*/;
Expand All @@ -8,57 +6,76 @@ const openAPIExtensions = /x-*/;
// message is str
// bool is boolean
function assert(bool, message) {
if (!bool) {
const err = message !== undefined ? new Error(message) : new Error("an error occured")
throw err
}
if (!bool) {
const err =
message !== undefined
? new Error(message)
: new Error("an error occured");
throw err;
}
}

function doRemoveParamFromNode(node, param) {
assert(typeof param === 'string', "extension must be a string")
assert(isExtensionValid(param), `[Aborting] String "${param}" is not a valid OpenAPI extension, it must begin with "x-"`)
delete node[param]
console.log('Deleteted extension "%s" from object "%O"', param, node)
assert(typeof param === "string", "extension must be a string");
assert(
isExtensionValid(param),
`[Aborting] String "${param}" is not a valid OpenAPI extension, it must begin with "x-"`
);
delete node[param];
console.log('Deleteted extension "%s" from object "%O"', param, node);
}

function isExtensionValid(extension) {
assert(typeof extension === 'string', "extension must be a string")
if (extension.match(openAPIExtensions)) {
return true
} else {
return false
}
assert(typeof extension === "string", "extension must be a string");
if (extension.match(openAPIExtensions)) {
return true;
} else {
return false;
}
}

function removeExtensionsFromNode(node, extensions) {
const extensionsType = typeof extensions
assert(extensionsType === undefined || extensionsType === 'string' || extensionsType === 'object', `Extensions must be a string or a list of string instead of being of type "${extensionsType}"`)
if (extensions === undefined || extensions === null || extensions === {} || extensions === '') {
console.log('Deleting all OpenAPI extensions (params starting with "x-")...')
Object.keys(node).filter(param => param.match(openAPIExtensions)).forEach((param) => {
doRemoveParamFromNode(node, param)
})
} else if (extensionsType === 'string') {
// extensions is a string representing a regex - delete all the params that match this regex
Object.keys(node).filter(param => param.match(extensions)).forEach((param) => {
doRemoveParamFromNode(node, param)
})
} else {
// extensions a list
// only return something if all strings are valid OpenAPI spec, otherwise panic (handled by the assert)
extensions.forEach((extension) => {
// extension is a string representing a regex - delete all the params that match this regex
Object.keys(node).filter(param => param.match(extension)).forEach((param) => {
doRemoveParamFromNode(node, param)
})
})
}
const extensionsType = typeof extensions;
Comment thread
tatomyr marked this conversation as resolved.
assert(
extensionsType === undefined ||
extensionsType === "string" ||
extensionsType === "object",
`Extensions must be a string or a list of string instead of being of type "${extensionsType}"`
);
if (extensions === undefined || extensions === null || extensions === "") {
console.log(
'Deleting all OpenAPI extensions (params starting with "x-")...'
);
Object.keys(node)
.filter((param) => param.match(openAPIExtensions))
.forEach((param) => {
doRemoveParamFromNode(node, param);
});
} else if (extensionsType === "string") {
// extensions is a string representing a regex - delete all the params that match this regex
Object.keys(node)
.filter((param) => param.match(extensions))
.forEach((param) => {
doRemoveParamFromNode(node, param);
});
} else {
// extensions a list
// only return something if all strings are valid OpenAPI spec, otherwise panic (handled by the assert)
extensions.forEach((extension) => {
// extension is a string representing a regex - delete all the params that match this regex
Object.keys(node)
.filter((param) => param.match(extension))
.forEach((param) => {
doRemoveParamFromNode(node, param);
});
});
}
}

function RemoveExtensions({extensions}) {
return {
any: {
enter: (node, _ctx) => removeExtensionsFromNode(node, extensions),
}
}
};
export default function RemoveExtensions({ extensions }) {
return {
any: {
enter: (node, _ctx) => removeExtensionsFromNode(node, extensions),
},
};
}
10 changes: 5 additions & 5 deletions custom-plugin-decorators/remove-unused-tags/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Remove unused tags

Authors:

- [`@lornajane`](https://github.com/lornajane), Lorna Mitchell (Redocly)


## What this does and why

Expand All @@ -17,7 +17,7 @@ This is a useful decorator to use when you are reducing a larger OpenAPI file fo
The plugin code itself is in `tags.js`:

```js
module.exports = {
export default function plugin() {
id: "tags",
decorators: {
oas3: {
Expand Down Expand Up @@ -60,7 +60,7 @@ To use the custom decorator, add configuration like the following to the `redocl

```yaml
plugins:
- './tags.js'
- ./tags.js

decorators:
tags/no-unused-tags: on
Expand All @@ -70,7 +70,7 @@ If there are tags that should be preserved even though they are unused, add them

```yaml
plugins:
- './tags.js'
- ./tags.js

decorators:
tags/no-unused-tags:
Expand All @@ -95,7 +95,7 @@ Start by adding the decorator to `redocly.yaml` and including some ignore settin

```yaml
plugins:
- './tags.js'
- ./tags.js

decorators:
tags/no-unused-tags:
Expand Down
2 changes: 1 addition & 1 deletion custom-plugin-decorators/remove-unused-tags/tags.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
export default function plugin() {
id: "tags",
decorators: {
oas3: {
Expand Down
72 changes: 37 additions & 35 deletions custom-plugin-decorators/swap-summary-description/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# Swap the summary and description fields

Authors:

- [`@lornajane`](https://github.com/lornajane), Lorna Mitchell (Redocly)

## What this does and why

We sometimes see API descriptions with the fields mixed up.
The most common of these is the `summary` and `description` fields on Operations in OpenAPI, some generators seem to produce the fields with the content reversed.

* Summary: used when the operations are displayed in a list, it should be a very short phrase to describe the operation.
* Description: used to supply more detail, used when the operation is displayed in detail. The description field also suports Markdown.
- Summary: used when the operations are displayed in a list, it should be a very short phrase to describe the operation.
- Description: used to supply more detail, used when the operation is displayed in detail. The description field also suports Markdown.

This decorator takes the content of both fields and (as long as there is some content in the description field), swaps them over.

Expand All @@ -18,35 +19,37 @@ This decorator takes the content of both fields and (as long as there is some co
The following code snippet shows the decorator, in a file named `swap-fields.js`:

```js
module.exports = {
id: "swap-fields",
decorators: {
oas3: {
"summary-description": () => {
return {
Operation: {
leave(target) {
let description = "";
let summary = "";
if (target.description) {
description = target.description
}
if (target.summary) {
summary = target.summary
}

// only swap them if there is some description content
if(description.length > 0){
target.description = summary;
target.summary = description;
}
export default function plugin() {
return {
id: "swap-fields",
decorators: {
oas3: {
"summary-description": () => {
return {
Operation: {
leave(target) {
let description = "";
let summary = "";
if (target.description) {
description = target.description;
}
if (target.summary) {
summary = target.summary;
}

// only swap them if there is some description content
if (description.length > 0) {
target.description = summary;
target.summary = description;
}
},
},
},
};
};
},
},
},
},
};
};
}
```

Put this file alongside your `redocly.yaml` file, and add the following configuration to `redocly.yaml`:
Expand Down Expand Up @@ -96,9 +99,8 @@ webhooks:
schema:
"$ref": "#/components/schemas/webhook-branch-protection-configuration-disabled"
responses:
'200':
description: Return a 200 status to indicate that the data was received
successfully
"200":
description: Return a 200 status to indicate that the data was received successfully

components:
schemas:
Expand All @@ -109,7 +111,7 @@ components:
action:
type: string
enum:
- disabled
- disabled
```

After the decorator has been run, the updated file looks like the following example:
Expand Down Expand Up @@ -143,9 +145,9 @@ webhooks:
content:
application/json:
schema:
$ref: '#/components/schemas/webhook-branch-protection-configuration-disabled'
$ref: "#/components/schemas/webhook-branch-protection-configuration-disabled"
responses:
'200':
"200":
description: Return a 200 status to indicate that the data was received successfully
components:
schemas:
Expand Down
Loading
Loading