From ad4713638895e844411fd2bb96c0412f95623369 Mon Sep 17 00:00:00 2001 From: Viacheslav Turovskyi Date: Thu, 14 Mar 2024 02:35:16 +0000 Subject: [PATCH] feat: add flag `moveAllToComponents` --- examples/index.js | 34 ++++++++++++++++++++++++---------- src/ComponentProvider.ts | 21 +++++++++++++-------- src/Optimizer.ts | 13 ++++++++----- src/index.d.ts | 1 + test/Optimizer.spec.ts | 33 ++++++++++++++++++++++++++++++--- 5 files changed, 76 insertions(+), 26 deletions(-) diff --git a/examples/index.js b/examples/index.js index bde9f745..2fcb1085 100644 --- a/examples/index.js +++ b/examples/index.js @@ -3,18 +3,32 @@ const { Optimizer } = require('../lib/Optimizer') // read input.yaml file synconously and store it as an string const input = require('fs').readFileSync('./examples/input.yaml', 'utf8') -const optimizer = new Optimizer(input) +const optimizer = new Optimizer(input, { + output: 'YAML', + rules: { + reuseComponents: true, + removeComponents: true, + moveAllToComponents: true, + moveDuplicatesToComponents: false, + schemas: false, + }, +}) optimizer.getReport().then((report) => { console.log(report) - const optimizedDocument = optimizer.getOptimizedDocument({ - output: 'YAML', - rules: { - reuseComponents: true, - removeComponents: true, - moveAllToComponents: true, - moveDuplicatesToComponents: false, - }, - }) + const optimizedDocument = optimizer.getOptimizedDocument( + // { + // output: 'YAML', + // rules: { + // reuseComponents: true, + // removeComponents: true, + // moveAllToComponents: true, + // moveDuplicatesToComponents: false, + // schemas: false, + // }, + // } + ) //store optimizedDocument as to output.yaml require('fs').writeFileSync('./examples/output.yaml', optimizedDocument) }) + +// , { rules: { schemas: false } } diff --git a/src/ComponentProvider.ts b/src/ComponentProvider.ts index 7f35ea0f..2c520604 100644 --- a/src/ComponentProvider.ts +++ b/src/ComponentProvider.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ /* eslint-disable security/detect-object-injection */ import type { AsyncAPIDocumentInterface } from '@asyncapi/parser' -import { OptimizableComponentGroup, OptimizableComponent } from 'index.d' +import { OptimizableComponentGroup, OptimizableComponent, Options } from 'index.d' import { JSONPath } from 'jsonpath-plus' import _ from 'lodash' @@ -53,15 +53,16 @@ export const parseComponentsFromPath = ( } export const getOptimizableComponents = ( - asyncAPIDocument: AsyncAPIDocumentInterface + asyncAPIDocument: AsyncAPIDocumentInterface, + options?: Options ): OptimizableComponentGroup[] => { const optimizeableComponents: OptimizableComponentGroup[] = [] const getAllComponents = (type: string) => { // @ts-ignore if (typeof asyncAPIDocument[type] !== 'function') return [] // @ts-ignore - return asyncAPIDocument[type]().all().concat(asyncAPIDocument.components()[type]().all()); - }; + return asyncAPIDocument[type]().all().concat(asyncAPIDocument.components()[type]().all()) + } const optimizableComponents = { servers: getAllComponents('servers'), messages: getAllComponents('messages'), @@ -83,10 +84,14 @@ export const getOptimizableComponents = ( operationBindings: getAllComponents('operationBindings'), messageBindings: getAllComponents('messageBindings'), } - // to remove `schemas` from the optimized AsyncAPI Document, uncomment the next line - // delete optimizableComponents.schemas - // const options = { includeSchemas: true } - // !options.includeSchemas && delete optimizableComponents.schemas + // In the case of `if (!options?.rules?.schemas)`, if `schemas` property is + // simply absent in the `options` object, the program's behavior will not turn + // to default `schemas: true`, but absence of `schemas` will be considered + // `schemas: false`, due to `undefined` being considered `false`. Thus, + // explicit check is performed. + if (options?.rules?.schemas === false) { + delete optimizableComponents.schemas + } for (const [type, components] of Object.entries(optimizableComponents)) { if (components.length === 0) continue optimizeableComponents.push({ diff --git a/src/Optimizer.ts b/src/Optimizer.ts index 2d98884a..dfb78ff2 100644 --- a/src/Optimizer.ts +++ b/src/Optimizer.ts @@ -45,7 +45,7 @@ export class Optimizer { /** * @param {any} YAMLorJSON - YAML or JSON document that you want to optimize. You can pass Object, YAML or JSON version of your AsyncAPI document here. */ - constructor(private YAMLorJSON: any) { + constructor(private YAMLorJSON: any, private options?: Options) { this.outputObject = toJS(this.YAMLorJSON) this.reporters = [ removeComponents, @@ -53,6 +53,7 @@ export class Optimizer { moveAllToComponents, moveDuplicatesToComponents, ] + this.options = options } /** @@ -67,7 +68,7 @@ export class Optimizer { console.error(parsedDocument.diagnostics) throw new Error('Parsing failed.') } - this.components = getOptimizableComponents(parsedDocument.document) + this.components = getOptimizableComponents(parsedDocument.document, this.options) const rawReports = this.reporters.map((reporter) => reporter(this.components)) const reportsWithParents = rawReports.map((report) => ({ type: report.type, @@ -89,6 +90,7 @@ export class Optimizer { * @property {Boolean=} removeComponents - whether to remove un-used components from `components` section or not. Defaults to `true`. * @property {Boolean=} moveAllToComponents - whether to move all AsyncAPI Specification-valid components to the `components` section or not. * @property {Boolean=} moveDuplicatesToComponents - whether to move duplicated components to the `components` section or not. Defaults to `true`. + * @property {Boolean=} schemas - whether to add calculated `schemas` to the optimized AsyncAPI Document. Defaults to `true`. */ /** @@ -108,12 +110,13 @@ export class Optimizer { rules: { reuseComponents: true, removeComponents: true, - moveAllToComponents: false, - moveDuplicatesToComponents: true, // there is no need to move duplicates if `moveAllToComponents` is true + moveAllToComponents: true, + moveDuplicatesToComponents: false, // there is no need to move duplicates if `moveAllToComponents` is `true` + schemas: true, }, output: Output.YAML, } - options = merge(defaultOptions, options) + options = merge(defaultOptions, this.options) if (!this.reports) { throw new Error( 'No report has been generated. please first generate a report by calling getReport method.' diff --git a/src/index.d.ts b/src/index.d.ts index d5cca558..9c25bc5b 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -35,6 +35,7 @@ interface Rules { removeComponents?: boolean moveAllToComponents?: boolean moveDuplicatesToComponents?: boolean + schemas?: boolean } export interface Options { rules?: Rules diff --git a/test/Optimizer.spec.ts b/test/Optimizer.spec.ts index b5b9c867..f9132870 100644 --- a/test/Optimizer.spec.ts +++ b/test/Optimizer.spec.ts @@ -4,19 +4,46 @@ import { Output } from '../src/Optimizer' describe('Optimizer', () => { it('should produce the correct optimized file with YAML input.', async () => { - const optimizer = new Optimizer(inputYAML) + const optimizer = new Optimizer(inputYAML, { + output: Output.YAML, + rules: { + reuseComponents: true, + removeComponents: true, + moveAllToComponents: false, + moveDuplicatesToComponents: true, + schemas: true, + }, + }) await optimizer.getReport() expect(optimizer.getOptimizedDocument().trim()).toEqual(outputYAML.trim()) }) it('should produce the correct optimized file with JSON input.', async () => { - const optimizer = new Optimizer(inputJSON) + const optimizer = new Optimizer(inputJSON, { + output: Output.YAML, + rules: { + reuseComponents: true, + removeComponents: true, + moveAllToComponents: false, + moveDuplicatesToComponents: true, + schemas: true, + }, + }) await optimizer.getReport() expect(optimizer.getOptimizedDocument().trim()).toEqual(outputYAML.trim()) }) it('should produce the correct JSON output.', async () => { - const optimizer = new Optimizer(inputYAML) + const optimizer = new Optimizer(inputYAML, { + output: Output.JSON, + rules: { + reuseComponents: true, + removeComponents: true, + moveAllToComponents: false, + moveDuplicatesToComponents: true, + schemas: true, + }, + }) await optimizer.getReport() expect(optimizer.getOptimizedDocument({ output: Output.JSON }).trim()).toEqual( outputJSON.trim()