mirror of
https://github.com/LukeHagar/redocly-cli.git
synced 2025-12-06 04:21:09 +00:00
feat: add support for a plugin interface common with Realm (#1661)
This commit is contained in:
committed by
GitHub
parent
9ce88a33a5
commit
7a0e52f57e
@@ -9,22 +9,24 @@ configuration file.
|
||||
The following is an example plugin, defining two configuration bundles:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
id: 'my-local-plugin'
|
||||
configs: {
|
||||
all: {
|
||||
rules: {
|
||||
'operation-id-not-test': 'error',
|
||||
'boolean-parameter-prefixes': 'error',
|
||||
module.exports = function myLocalPlugin() {
|
||||
return {
|
||||
id: 'my-local-plugin',
|
||||
configs: {
|
||||
all: {
|
||||
rules: {
|
||||
'operation-id-not-test': 'error',
|
||||
'boolean-parameter-prefixes': 'error',
|
||||
},
|
||||
},
|
||||
minimal: {
|
||||
rules: {
|
||||
'operation-id-not-test': 'off',
|
||||
'boolean-parameter-prefixes': 'error',
|
||||
},
|
||||
},
|
||||
},
|
||||
minimal: {
|
||||
rules: {
|
||||
'operation-id-not-test': 'off',
|
||||
'boolean-parameter-prefixes': 'error',
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
@@ -13,26 +13,29 @@ Decorators and preprocessors are the same in structure, but preprocessors are ru
|
||||
|
||||
## Plugin structure
|
||||
|
||||
To create a preprocessor or decorator, the object that is exported from your module has to conform to an interface such as the following example:
|
||||
To create a preprocessor or decorator, the function that is exported from your module has to conform to an interface such as the following example:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
id: 'my-local-plugin',
|
||||
preprocessors: {
|
||||
oas3: {
|
||||
"processor-id": () => {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
},
|
||||
decorators: {
|
||||
oas3: {
|
||||
"decorator-id": () => {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
module.exports = function myLocalPlugin() {
|
||||
return {
|
||||
id: 'my-local-plugin',
|
||||
preprocessors: {
|
||||
oas3: {
|
||||
'processor-id': () => {
|
||||
// ...
|
||||
},
|
||||
},
|
||||
},
|
||||
decorators: {
|
||||
oas3: {
|
||||
'decorator-id': () => {
|
||||
// ...
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
Each decorator or preprocessor is a function that returns an object. The object's keys are the node types in the document, and each of those can contain any or all of the `enter()`, `leave()` and `skip()` functions for that node type. Find more information and examples on the [visitor pattern page](./visitor.md).
|
||||
@@ -67,14 +70,16 @@ To use this decorator, add it to a plugin. In this example the main decorator fi
|
||||
```js
|
||||
const OperationSparkle = require('./decorators/operation-sparkle.js');
|
||||
|
||||
module.exports = {
|
||||
id: 'sparkle',
|
||||
decorators: {
|
||||
oas3: {
|
||||
'operation-sparkle': OperationSparkle,
|
||||
}
|
||||
}
|
||||
};
|
||||
module.exports = function sparklePlugin() {
|
||||
return {
|
||||
id: "sparkle",
|
||||
decorators: {
|
||||
oas3: {
|
||||
"operation-sparkle": OperationSparkle,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
The plugin is good to go. For a user to include it in their Redocly configuration, edit the configuration file to look something like this:
|
||||
@@ -118,15 +123,17 @@ Now extend the decorator from the previous example to add this to the existing p
|
||||
const OperationSparkle = require('./decorators/operation-sparkle.js');
|
||||
const OpIdSuffix = require('./decorators/add-suffix.js');
|
||||
|
||||
module.exports = {
|
||||
id: 'sparkle',
|
||||
decorators: {
|
||||
oas3: {
|
||||
'operation-sparkle': OperationSparkle,
|
||||
'add-opid-suffix': OpIdSuffix,
|
||||
}
|
||||
}
|
||||
};
|
||||
module.exports = function sparklePlugin() {
|
||||
return {
|
||||
id: "sparkle",
|
||||
decorators: {
|
||||
oas3: {
|
||||
"operation-sparkle": OperationSparkle,
|
||||
"add-opid-suffix": OpIdSuffix,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
All that remains is for a user to configure this decorator in their `redocly.yaml` configuration file to take advantage of the new decorator functionality. Here's an example of the configuration file:
|
||||
|
||||
@@ -35,18 +35,21 @@ function OperationIdNotTest() {
|
||||
|
||||
The `ctx` object here holds all the context, which can be used to give more situation-aware functionality to the rules you build. This is one of the main use cases for custom rules. The `report()` method is used to give information to return to the user if the node being visited doesn't comply with the rule. You can read the [context](#the-context-object) and [location](#location-object) sections for more information.
|
||||
|
||||
Adding this as part of a plugin requires you to add it to the `rules` part of the plugin object, under the relevant document type. The example rule here is intended to be used with OpenAPI, so the plugin code in `plugins/my-rules.js` is as follows:
|
||||
Adding this as part of a plugin requires you to add it to the `rules` part of the plugin object returned by the exported function, under the relevant document type.
|
||||
The example rule here is intended to be used with OpenAPI, so the plugin code in `plugins/my-rules.js` is as follows:
|
||||
|
||||
```js
|
||||
const OperationIdNotTest = require('./rules/opid-not-test.js');
|
||||
|
||||
module.exports = {
|
||||
id: 'my-rules',
|
||||
rules: {
|
||||
oas3: {
|
||||
'opid-not-test': OperationIdNotTest,
|
||||
}
|
||||
},
|
||||
module.exports = function myRulesPlugin() {
|
||||
return {
|
||||
id: 'my-rules',
|
||||
rules: {
|
||||
oas3: {
|
||||
'opid-not-test': OperationIdNotTest,
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
@@ -38,23 +38,25 @@ Note the quotes around the `owner-team` key since it contains a hyphen `-`. Thes
|
||||
To include the new type in the type tree, the plugin must add the type and modify the parent type, which in this example is `info`. This is done by returning a `typeExtension` structure, as shown in the example below (this example is in `plugins/example-type-extension.js`, this filename is used again in the configuration example later):
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
id: 'example-type-extension',
|
||||
typeExtension: {
|
||||
oas3(types) {
|
||||
return {
|
||||
...types,
|
||||
XMetaData: XMetaData,
|
||||
Info: {
|
||||
...types.Info,
|
||||
properties: {
|
||||
...types.Info.properties,
|
||||
'x-metadata': 'XMetaData',
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
module.exports = function typeExtensionsPlugin() {
|
||||
return {
|
||||
id: 'example-type-extension',
|
||||
typeExtension: {
|
||||
oas3(types) {
|
||||
return {
|
||||
...types,
|
||||
XMetaData: XMetaData,
|
||||
Info: {
|
||||
...types.Info,
|
||||
properties: {
|
||||
...types.Info.properties,
|
||||
'x-metadata': 'XMetaData',
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
@@ -43,11 +43,13 @@ The paths are relative to the configuration file location. Where there are multi
|
||||
|
||||
### Plugin structure
|
||||
|
||||
The minimal plugin should export an `id` string that is used to refer to the contents of the plugin in the `redocly.yaml` configuration file:
|
||||
The minimal plugin should export a function that returns an object with a single property `id` that is used to refer to the contents of the plugin in the `redocly.yaml` configuration file:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
id: 'my-local-plugin',
|
||||
module.exports = function myPlugin() {
|
||||
return {
|
||||
id: 'my-local-plugin',
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
@@ -34,9 +34,11 @@ Estimated time: 15 minutes
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
id,
|
||||
decorators,
|
||||
module.exports = function changeTokenPlugin() {
|
||||
return {
|
||||
id,
|
||||
decorators,
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
@@ -44,9 +44,11 @@ In this step, create a custom plugin and define the decorator dependency.
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
id,
|
||||
decorators,
|
||||
module.exports = function hideExtensionsPlugin() {
|
||||
return {
|
||||
id,
|
||||
decorators,
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
@@ -84,9 +84,11 @@ const decorators = {
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
id,
|
||||
decorators,
|
||||
module.exports = function replaceServersUrlPlugin() {
|
||||
return {
|
||||
id,
|
||||
decorators,
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
@@ -242,34 +242,36 @@ rule/operation-summary-check:
|
||||
`plugin.js`
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
id: 'local',
|
||||
assertions: {
|
||||
checkWordsStarts: (value, options, ctx) => {
|
||||
const regexp = new RegExp(`^${options.words.join('|')}`);
|
||||
if (regexp.test(value)) {
|
||||
return [];
|
||||
}
|
||||
return [
|
||||
{
|
||||
message: 'Operation summary should start with an active verb',
|
||||
location: ctx.baseLocation,
|
||||
},
|
||||
];
|
||||
module.exports = function localPlugin() {
|
||||
return {
|
||||
id: 'local',
|
||||
assertions: {
|
||||
checkWordsStarts: (value, options, ctx) => {
|
||||
const regexp = new RegExp(`^${options.words.join('|')}`);
|
||||
if (regexp.test(value)) {
|
||||
return [];
|
||||
}
|
||||
return [
|
||||
{
|
||||
message: 'Operation summary should start with an active verb',
|
||||
location: ctx.baseLocation,
|
||||
},
|
||||
];
|
||||
},
|
||||
checkWordsCount: (value, options, ctx) => {
|
||||
const words = value.split(' ');
|
||||
if (words.length >= options.min) {
|
||||
return [];
|
||||
}
|
||||
return [
|
||||
{
|
||||
message: `Operation summary should contain at least ${options.min} words`,
|
||||
location: ctx.baseLocation,
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
checkWordsCount: (value, options, ctx) => {
|
||||
const words = value.split(' ');
|
||||
if (words.length >= options.min) {
|
||||
return [];
|
||||
}
|
||||
return [
|
||||
{
|
||||
message: `Operation summary should contain at least ${options.min} words`,
|
||||
location: ctx.baseLocation,
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user