Skip to content

Commit

Permalink
feat: enable report generation (#8)
Browse files Browse the repository at this point in the history
Co-authored-by: Maciej Urbańczyk <urbanczyk.maciej.95@gmail.com>
Co-authored-by: Lukasz Gornicki <lpgornicki@gmail.com>
  • Loading branch information
3 people committed Aug 10, 2021
1 parent d15f1e1 commit 63b9047
Show file tree
Hide file tree
Showing 21 changed files with 4,448 additions and 2,461 deletions.
3 changes: 2 additions & 1 deletion .eslintignore
Expand Up @@ -3,4 +3,5 @@ node_modules
.idea
coverage
lib
*.DS_Store
*.DS_Store
examples
5 changes: 4 additions & 1 deletion .eslintrc
Expand Up @@ -13,7 +13,10 @@
"plugin:security/recommended"
],
"rules": {
"@typescript-eslint/no-unused-vars": ["error"],
"strict": 0,
"object-curly-spacing": ["error", "always"],
"comma-spacing": ["error", { "before": false, "after": true }],
"github/array-foreach": 2,
"eol-last": ["error", "always"],
"@typescript-eslint/no-explicit-any": 0,
Expand Down Expand Up @@ -203,4 +206,4 @@
}
}
]
}
}
83 changes: 39 additions & 44 deletions README.md
@@ -1,5 +1,11 @@
# optimizer
AsyncAPI offers many ways to reuse certain parts of the document like messages or schemas definitions or references to external files, not to even mention the traits. There is a need for a tool that can be plugged into any workflows and optimize documents that are generated from code, but not only.
# Optimizer
AsyncAPI offers many ways to reuse certain parts of the document like messages or schemas definitions or references to external files, not to even mention the traits. Purpose of **AsyncAPI Optimizer** is to enable different ways to optimize AsyncAPI files. It is a library that can be used in UIs and CLIs.
## Testing
1) Clone the project
`git https://github.com/asyncapi/optimizer.git`
2) Install the dependencies
`npm i`
3) for a quick check you can run `npm run example`. You can open `examples/index.js` modify it or add your own AsyncAPI document for optimization.

## Usage

Expand All @@ -8,9 +14,8 @@ AsyncAPI offers many ways to reuse certain parts of the document like messages o
```typescript
import { Optimizer } from '@asyncapi/optimizer';
import type { Report } from '@asyncapi/optimizer';
import { parse } from '@asyncapi/parser';

const asyncApiDocument = parse(`
const yaml =`
asyncapi: 2.0.0
info:
title: Streetlights API
Expand Down Expand Up @@ -92,10 +97,9 @@ components:
#this schema is ref-ed in one channel and used full form in another. library should be able to identify and ref the second channel as well.
sentAt:
type: string
format: date-time`
);
format: date-time`;

const optimizer = new Optimizer(asyncApiDocument);
const optimizer = new Optimizer(yaml);
```
### Generating report
```typescript
Expand All @@ -105,28 +109,28 @@ the report value will be:
{
reuseComponents: [
{
path: '#/channels/channel1/smartylighting/event/{streetlightId}/lighting/measured/message/payload/properties/sentAt',
path: 'channels.smartylighting/event/{streetlightId}/lighting/measured.message.payload.properties.sentAt',
action: 'reuse',
target: '#/components/schemas/sentAt'
target: 'components.schemas.sentAt'
}
],
removeComponents: [
{
path: '#/components/messages/unusedMessage',
path: 'components.messages.unusedMessage',
action: 'remove',
}
],
moveToComponents: [
{
//move will ref the current path to the moved component as well.
path: '#/channels/smartylighting/event/{streetlightId}/lighting/measured/parameters/streetlightId',
path: 'channels.smartylighting/event/{streetlightId}/lighting/measured.parameters.streetlightId',
action: 'move',
target: '#/components/parameters/streetlightId'
target: 'components.parameters.streetlightId'
},
{
path: '#/channels/smartylighting/action/{streetlightId}/turn/on/parameters/streetlightId',
path: 'channels.smartylighting/action/{streetlightId}/turn/on.parameters.streetlightId',
action: 'reuse',
target: '#/components/parameters/streetlightId'
target: 'components.parameters.streetlightId'
}
]
}
Expand All @@ -147,14 +151,12 @@ the optimizedDocument value will be:
asyncapi: 2.0.0
info:
title: Streetlights API
version: '1.0.0'
version: 1.0.0
channels:
smartylighting/event/{streetlightId}/lighting/measured:
"smartylighting/event/{streetlightId}/lighting/measured":
parameters:
streetlightId:
$ref: "#/components/schemas/streetlightId"
$ref: "#/components/parameters/parameter-1"
subscribe:
operationId: receiveLightMeasurement
traits:
Expand All @@ -167,26 +169,19 @@ channels:
contentType: application/json
traits:
- headers:
type: object
properties:
my-app-header:
type: integer
minimum: 0
maximum: 100
$ref: "#/components/schemas/schema-1"
payload:
type: object
properties:
lumens:
type: integer
minimum: 0
#full form is used, we can ref it to: #/components/schemas/sentAt
sentAt:
$ref: "#/components/schemas/sentAt"
smartylighting/action/{streetlightId}/turn/on:
"smartylighting/action/{streetlightId}/turn/on":
parameters:
streetlightId:
$ref: "#/components/schemas/streetlightId"
$ref: "#/components/parameters/parameter-1"
publish:
operationId: turnOn
traits:
Expand All @@ -198,28 +193,28 @@ channels:
title: Turn on/off
traits:
- headers:
type: object
properties:
my-app-header:
type: integer
minimum: 0
maximum: 100
$ref: "#/components/schemas/schema-1"
payload:
type: object
properties:
sentAt:
$ref: "#/components/schemas/sentAt"
components:
parameters:
streetlightId:
schema:
type: string
schemas:
#this schema is ref-ed in one channel and used full form in another. library should be able to identify and ref the second channel as well.
sentAt:
type: string
format: date-time`
format: date-time
schema-1:
type: object
properties:
my-app-header:
type: integer
minimum: 0
maximum: 100
parameters:
parameter-1:
schema:
type: string`
*/
```

Expand All @@ -229,11 +224,11 @@ components:

#### new Optimizer(document)

`document` is a mandatory object which is the parsed AsyncAPI specification from `@asyncapi/parser`:
`document` is a mandatory object which is a string of asyncapi yaml file:

### Methods

#### getReport(): OptimizerReport
#### getReport(): Promise<OptimizerReport>
`OptimizerReport` is an object that will be returned by this function. This object will contain all the suggested changes by the optimizer grouped by their category.
#### getOptimizedDocument([options]): string
`options` is an OPTIONAL object that contains the following customizations:
Expand Down
92 changes: 92 additions & 0 deletions examples/index.js
@@ -0,0 +1,92 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { Optimizer } = require('../lib/Optimizer');

const yaml = `
asyncapi: 2.0.0
info:
title: Streetlights API
version: '1.0.0'
channels:
smartylighting/event/{streetlightId}/lighting/measured:
parameters:
#this parameter is duplicated. it can be moved to components and ref-ed from here.
streetlightId:
schema:
type: string
subscribe:
operationId: receiveLightMeasurement
traits:
- bindings:
kafka:
clientId: my-app-id
message:
name: lightMeasured
title: Light measured
contentType: application/json
traits:
- headers:
type: object
properties:
my-app-header:
type: integer
minimum: 0
maximum: 100
payload:
type: object
properties:
lumens:
type: integer
minimum: 0
#full form is used, we can ref it to: #/components/schemas/sentAt
sentAt:
type: string
format: date-time
smartylighting/action/{streetlightId}/turn/on:
parameters:
streetlightId:
schema:
type: string
publish:
operationId: turnOn
traits:
- bindings:
kafka:
clientId: my-app-id
message:
name: turnOnOff
title: Turn on/off
traits:
- headers:
type: object
properties:
my-app-header:
type: integer
minimum: 0
maximum: 100
payload:
type: object
properties:
sentAt:
$ref: "#/components/schemas/sentAt"
components:
messages:
#libarary should be able to find and delete this message, because it is not used anywhere.
unusedMessage:
name: unusedMessage
title: This message is not used in any channel.
schemas:
#this schema is ref-ed in one channel and used full form in another. library should be able to identify and ref the second channel as well.
sentAt:
type: string
format: date-time`;
const optimizer = new Optimizer(yaml);
optimizer.getReport().then(report => {
console.log(report);
const optimizedDocument = optimizer.getOptimizedDocument({ rules: {
reuseComponents: true,
removeComponents: true,
moveToComponents: true
} });
console.log(optimizedDocument);
});

0 comments on commit 63b9047

Please sign in to comment.