diff --git a/src/models/v3/message-base.ts b/src/models/v3/message-base.ts new file mode 100644 index 000000000..9d06c600b --- /dev/null +++ b/src/models/v3/message-base.ts @@ -0,0 +1,69 @@ +import { CorrelationId } from './correlation-id'; +import { MessageExamples } from './message-examples'; +import { MessageExample } from './message-example'; +import { Schema } from './schema'; + +import { xParserMessageName } from '../../constants'; +import { CoreModel } from './mixins'; + +import type { CorrelationIdInterface } from '../correlation-id'; +import type { MessageExamplesInterface } from '../message-examples'; +import type { SchemaInterface } from '../schema'; + +import type { v3 } from '../../spec-types'; + +export class MessageBase extends CoreModel { + id(): string { + return this.messageId() || this._meta.id || this.extensions().get(xParserMessageName)?.value() as string; + } + + hasMessageId(): boolean { + return !!this._json.messageId; + } + + messageId(): string | undefined { + return this._json.messageId; + } + + hasCorrelationId(): boolean { + return !!this._json.correlationId; + } + + correlationId(): CorrelationIdInterface | undefined { + if (!this._json.correlationId) return undefined; + return this.createModel(CorrelationId, this._json.correlationId as v3.CorrelationIDObject, { pointer: this.jsonPath('correlationId') }); + } + + hasContentType(): boolean { + return !!this._json.contentType; + } + + contentType(): string | undefined { + return this._json.contentType || this._meta.asyncapi?.parsed?.defaultContentType; + } + + hasHeaders(): boolean { + return !!this._json.headers; + } + + headers(): SchemaInterface | undefined { + if (!this._json.headers) return undefined; + return this.createModel(Schema, this._json.headers, { pointer: this.jsonPath('headers') }); + } + + hasName(): boolean { + return !!this._json.name; + } + + name(): string | undefined { + return this._json.name; + } + + examples(): MessageExamplesInterface { + return new MessageExamples( + (this._json.examples || []).map((example: any, index: number) => { + return this.createModel(MessageExample, example, { pointer: this.jsonPath(`examples/${index}`) }); + }) + ); + } +} diff --git a/src/models/v3/message.ts b/src/models/v3/message.ts index c7fce9f5d..ce05a9e3d 100644 --- a/src/models/v3/message.ts +++ b/src/models/v3/message.ts @@ -28,6 +28,19 @@ export class Message extends MessageTrait implements MessageIn return this.createModel(Schema, this._json.payload, { pointer: this.jsonPath('payload')}); } + hasSchemaFormat(): boolean { + // If it has a payload, schema format is expected (at least the default) + return this.hasPayload(); + } + + schemaFormat(): string | undefined { + if (this.hasSchemaFormat()) { + return this.payload()?.schemaFormat(); + } + + return undefined; + } + servers(): ServersInterface { const servers: ServerInterface[] = []; const serversData: any[] = []; diff --git a/test/models/v2/message.spec.ts b/test/models/v2/message.spec.ts index 111031476..ab445a87e 100644 --- a/test/models/v2/message.spec.ts +++ b/test/models/v2/message.spec.ts @@ -26,16 +26,18 @@ describe('Message model', function() { }); }); - describe('.schemaFormat()', function() { + describe('.schemaFormat() + .hasSchemaFormat()', function() { it('should return defined schemaFormat', function() { const doc = { schemaFormat: 'customSchemaFormat' }; const d = new Message(doc, { asyncapi: {} as any, pointer: '', id: 'message' }); + expect(d.hasSchemaFormat()).toBeTruthy(); expect(d.schemaFormat()).toEqual('customSchemaFormat'); }); it('should return default schemaFormat if schemaFormat field is absent', function() { const doc = {}; const d = new Message(doc, { asyncapi: { semver: { version: '2.0.0' } } as any, pointer: '', id: 'message' }); + expect(d.hasSchemaFormat()).toBeTruthy(); expect(d.schemaFormat()).toEqual('application/vnd.aai.asyncapi;version=2.0.0'); }); }); diff --git a/test/models/v3/message.spec.ts b/test/models/v3/message.spec.ts index f4ebc3d5c..91432f36d 100644 --- a/test/models/v3/message.spec.ts +++ b/test/models/v3/message.spec.ts @@ -20,6 +20,29 @@ describe('Message model', function() { }); }); + describe('.schemaFormat() + .hasSchemaFormat()', function() { + it('should return defined schemaFormat, and true for hasSchemaFormat()', function() { + const doc = { payload: {schemaFormat: 'customSchemaFormat', schema: {} }}; + const d = new Message(doc, { asyncapi: {} as any, pointer: '', id: 'message' }); + expect(d.hasSchemaFormat()).toBeTruthy(); + expect(d.schemaFormat()).toEqual('customSchemaFormat'); + }); + + it('should return default schemaFormat if schemaFormat field is absent', function() { + const doc = {payload: {}}; + const d = new Message(doc, { asyncapi: { semver: { version: '2.0.0' } } as any, pointer: '', id: 'message' }); + expect(d.hasSchemaFormat()).toBeTruthy(); + expect(d.schemaFormat()).toEqual('application/vnd.aai.asyncapi;version=2.0.0'); + }); + + it('should return undefined schemaFormat, and false for hasSchemaFormat() if there is no payload', function() { + const doc = {}; + const d = new Message(doc, { asyncapi: { semver: { version: '2.0.0' } } as any, pointer: '', id: 'message' }); + expect(d.hasSchemaFormat()).toBeFalsy(); + expect(d.schemaFormat()).toBeUndefined(); + }); + }); + describe('.hasPayload()', function() { it('should return true when there is a value', function() { const doc = { payload: {} };