diff --git a/package.json b/package.json index 099f0984f01..a1caf18f31d 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "bugs": "https://github.com/asyncapi/cli/issues", "dependencies": { "@asyncapi/avro-schema-parser": "^3.0.22", - "@asyncapi/bundler": "^0.4.0", + "@asyncapi/bundler": "^0.5.0", "@asyncapi/converter": "^1.4.19", "@asyncapi/diff": "^0.4.1", "@asyncapi/generator": "^1.17.25", diff --git a/src/commands/bundle.ts b/src/commands/bundle.ts index 481973f935a..f9444268593 100644 --- a/src/commands/bundle.ts +++ b/src/commands/bundle.ts @@ -4,49 +4,44 @@ import Command from '../base'; import bundle from '@asyncapi/bundler'; import { promises } from 'fs'; import path from 'path'; -import { Specification, load } from '../models/SpecificationFile'; -import { Parser } from '@asyncapi/parser'; +import { Specification } from '../models/SpecificationFile'; import { Document } from '@asyncapi/bundler/lib/document'; const { writeFile } = promises; export default class Bundle extends Command { - static description = 'bundle one or multiple asyncapi documents and their references together.'; + static description = 'Bundle one or multiple AsyncAPI Documents and their references together.'; static strict = false; static examples: Example[] = [ - 'asyncapi bundle ./asyncapi.yaml > final-asyncapi.yaml', 'asyncapi bundle ./asyncapi.yaml --output final-asyncapi.yaml', - 'asyncapi bundle ./asyncapi.yaml ./features.yaml --reference-into-components', - 'asyncapi bundle ./asyncapi.yaml ./features.yaml --base ./asyncapi.yaml --reference-into-components' + 'asyncapi bundle ./asyncapi.yaml ./features.yaml', + 'asyncapi bundle ./asyncapi.yaml ./features.yaml --base ./main.yaml', + 'asyncapi bundle ./asyncapi.yaml ./features.yaml --base ./main.yaml --xOrigin', + 'asyncapi bundle ./asyncapi.yaml -o final-asyncapi.yaml --base ../public-api/main.yaml --baseDir ./social-media/comments-service', ]; static flags = { help: Flags.help({ char: 'h' }), output: Flags.string({ char: 'o', description: 'The output file name. Omitting this flag the result will be printed in the console.' }), - 'reference-into-components': Flags.boolean({ char: 'r', description: 'Bundle the message $refs into components object.' }), - base: Flags.string({ char: 'b', description: 'Path to the file which will act as a base. This is required when some properties are to needed to be overwritten.' }), + base: Flags.string({ char: 'b', description: 'Path to the file which will act as a base. This is required when some properties need to be overwritten.' }), + baseDir: Flags.string({ char: 'd', description: 'One relative/absolute path to directory relative to which paths to AsyncAPI Documents that should be bundled will be resolved.' }), + xOrigin: Flags.boolean({ char: 'x', description: 'Pass this switch to generate properties "x-origin" that will contain historical values of dereferenced "$ref"s.' }), }; - parser = new Parser(); - async run() { const { argv, flags } = await this.parse(Bundle); const output = flags.output; - let baseFile; const outputFormat = path.extname(argv[0]); - const AsyncAPIFiles = await this.loadFiles(argv); - - this.metricsMetadata.files = AsyncAPIFiles.length; - - if (flags.base) {baseFile = (await load(flags.base)).text();} + const AsyncAPIFiles = argv; - const fileContents = AsyncAPIFiles.map((file) => file.text()); + this.metricsMetadata.files = AsyncAPIFiles.length; - const document = await bundle(fileContents, + const document = await bundle(AsyncAPIFiles, { - referenceIntoComponents: flags['reference-into-components'], - base: baseFile + base: flags.base, + baseDir: flags.baseDir, + xOrigin: flags.xOrigin, } ); @@ -87,12 +82,4 @@ export default class Bundle extends Command { } } - async loadFiles(filepaths: string[]): Promise { - const files = []; - for (const filepath of filepaths) { - const file = await load(filepath); - files.push(file); - } - return files; - } } diff --git a/src/models/SpecificationFile.ts b/src/models/SpecificationFile.ts index 857ac471cf4..d81c84b1a41 100644 --- a/src/models/SpecificationFile.ts +++ b/src/models/SpecificationFile.ts @@ -222,4 +222,3 @@ async function detectSpecFile(): Promise { })); return existingFileNames.find(filename => filename !== undefined); } - diff --git a/test/integration/bundle/bundle.test.ts b/test/integration/bundle/bundle.test.ts index 0cc20e7cb31..f1ac4bf776a 100644 --- a/test/integration/bundle/bundle.test.ts +++ b/test/integration/bundle/bundle.test.ts @@ -45,25 +45,14 @@ describe('bundle', () => { 'bundle', './test/integration/bundle/asyncapi.yml' ]) .it('should throw error message if the file path is wrong', (ctx, done) => { - expect(ctx.stderr).to.contain('error loading AsyncAPI document from file: ./test/integration/bundle/asyncapi.yml file does not exist.\n'); + expect(ctx.stderr).to.contain('Error: ENOENT: no such file or directory'); done(); }); test .stdout() .command([ - 'bundle', './test/integration/bundle/first-asyncapi.yaml', '--reference-into-components', '--output=./test/integration/bundle/final.yaml' - ]) - .it('should be able to refence messages into components', (ctx, done) => { - expect(ctx.stdout).to.contain('Check out your shiny new bundled files at ./test/integration/bundle/final.yaml\n'); - fileCleanup('./test/integration/bundle/final.yaml'); - done(); - }); - - test - .stdout() - .command([ - 'bundle', './test/integration/bundle/first-asyncapi.yaml', './test/integration/bundle/feature.yaml', '--reference-into-components', '--output=test/integration/bundle/final.yaml' + 'bundle', './test/integration/bundle/first-asyncapi.yaml', './test/integration/bundle/feature.yaml', '--output=test/integration/bundle/final.yaml' ]) .it('should be able to bundle multiple specs along with custom reference', (ctx, done) => { expect(ctx.stdout).to.contain('Check out your shiny new bundled files at test/integration/bundle/final.yaml\n'); @@ -75,7 +64,7 @@ describe('bundle', () => { test .stdout() .command([ - 'bundle', './test/integration/bundle/first-asyncapi.yaml', './test/integration/bundle/feature.yaml', '--reference-into-components', '--output=test/integration/bundle/final.yaml', '--base=./test/integration/bundle/first-asyncapi.yaml' + 'bundle', './test/integration/bundle/first-asyncapi.yaml', './test/integration/bundle/feature.yaml', '--output=test/integration/bundle/final.yaml', '--base=./test/integration/bundle/first-asyncapi.yaml' ]) .it('should be able to bundle correctly with overwriting base file', (ctx, done) => { expect(ctx.stdout).to.contain('Check out your shiny new bundled files at test/integration/bundle/final.yaml\n'); diff --git a/test/integration/bundle/channels.yaml b/test/integration/bundle/channels.yaml new file mode 100644 index 00000000000..b1794157960 --- /dev/null +++ b/test/integration/bundle/channels.yaml @@ -0,0 +1,3 @@ +channels: + commentLikedChannel: + address: comment/liked \ No newline at end of file diff --git a/test/integration/bundle/feature.yaml b/test/integration/bundle/feature.yaml index f3b41b9e0b4..1a716520cc9 100644 --- a/test/integration/bundle/feature.yaml +++ b/test/integration/bundle/feature.yaml @@ -1,11 +1,10 @@ -asyncapi: "2.5.0" +asyncapi: "2.6.0" info: title: Account Service version: 1.0.0 description: This service is in charge of processing user logouts channels: user/loggedOut: - subcribe: + unsubcribe: message: $ref: 'test/integration/bundle/messages.yaml#/messages/UserLoggedOut' - diff --git a/test/integration/bundle/final-asyncapi.yaml b/test/integration/bundle/final-asyncapi.yaml index 4624b746503..9de32aa5d81 100644 --- a/test/integration/bundle/final-asyncapi.yaml +++ b/test/integration/bundle/final-asyncapi.yaml @@ -1,4 +1,4 @@ -asyncapi: 2.5.0 +asyncapi: 2.6.0 info: title: Account Service version: 1.0.0 @@ -9,7 +9,7 @@ channels: message: $ref: '#/components/messages/UserSignedUp' user/loggedOut: - subcribe: + unsubcribe: message: $ref: '#/components/messages/UserLoggedOut' components: @@ -38,4 +38,3 @@ components: timestamp: type: number descriptio: Time stamp when the user logged out - diff --git a/test/integration/bundle/first-asyncapi.yaml b/test/integration/bundle/first-asyncapi.yaml index f49894d1d7f..d41ed4a2fec 100644 --- a/test/integration/bundle/first-asyncapi.yaml +++ b/test/integration/bundle/first-asyncapi.yaml @@ -1,4 +1,4 @@ -asyncapi: "2.5.0" +asyncapi: "2.6.0" info: title: Account Service version: 1.0.0 diff --git a/test/integration/bundle/first-asyncapiv3.yaml b/test/integration/bundle/first-asyncapiv3.yaml index 117d7bad68c..d49bb67334c 100644 --- a/test/integration/bundle/first-asyncapiv3.yaml +++ b/test/integration/bundle/first-asyncapiv3.yaml @@ -1,34 +1,8 @@ asyncapi: 3.0.0 info: - title: Account Service + title: Example Service version: 1.0.0 - description: This service is in charge of processing user signupsA + description: Example Service. channels: - userSignedup: - address: 'user/signedup' - messages: - userSignedUpMessage: - $ref: './test/integration/bundle/messages.yaml#/messages/UserSignedUp' - test: - address: '/test' - messages: - testMessage: - $ref: '#/components/messages/TestMessage' -operations: - UserSignedUp: - action: send - channel: - $ref: '#/channels/userSignedup' - messages: - - $ref: './test/integration/bundle/messages.yaml#/messages/UserSignedUp' - TestOpp: - action: send - channel: - $ref: '#/channels/test' - messages: - - $ref: '#/components/messages/TestMessage' -components: - messages: - TestMessage: - payload: - type: string \ No newline at end of file + commentLikedChannel: + $ref: './test/integration/bundle/channels.yaml#/channels/commentLikedChannel'