Skip to content

Commit

Permalink
Merge pull request #52 from WaleedAshraf/messageId
Browse files Browse the repository at this point in the history
add support for messageId
  • Loading branch information
WaleedAshraf authored May 22, 2022
2 parents 6c4e01c + 87e2013 commit 34ef690
Show file tree
Hide file tree
Showing 21 changed files with 12,256 additions and 3,779 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
Change Log
==========

Version 4.0.0 *(2022-05-22)*
----------------------------
### Breaking:
* "should" replaced with "must" in the error messages, as per [in AJV](https://github.com/ajv-validator/ajv/blob/master/docs/v6-to-v8-migration.md#new-features)

### New / Improvements:
* Support AsyncAPI schema v2.4.0
* Added `validateByMessageId()` method, which only requires `key` and `value`. To use this method, your AsyncAPI schema should be >= 2.4.0. `messageId` should be defined in schema as per [AsyncAPI 2.4.0 schema definition](https://www.asyncapi.com/docs/specifications/v2.4.0#messageObject).
* `msgIdentifier` option is only required if you use `.validate()` method.
* You can use both `validateByMessageId()` and `validate()` methods if your AsyncAPI schema version is >= 2.4.0
* Start using `ajv-formats` for custom formats.

Version 3.2.0 *(2022-03-22)*
----------------------------
* Option to provide `path` parameter for relative file ref.
Expand Down
97 changes: 73 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,31 @@

# asyncapi-validator

message validator through asyncapi schema
Message validator through AsyncAPI schema

_Note: This package only support AsyncAPI Schema v2.0.0 and above. Since v3.0.0, support for older versions of AsyncAPI Schema has been removed.

`npm i asyncapi-validator`

## Features
- Validate your AsyncApi Document against AsyncApi Schema definition
- Validate your messages against your AsyncApi Document
- Validate your AsyncApi Document against AsyncApi Schema definition
- Load your AsyncApi Schema from local file or any URL
- Supports AsyncApi in JSON and YAML format
- Supports AsyncAPI v2.0.0 and above
- more coming . . .

## Content
- [Class Methods](#class-methods)
- [AsyncApiValidator.fromSource()](#asyncapivalidatorfromsource)
- [Options](#options)
- [Instance Methods / Properties](#instance-methods--properties)
- [.validateByMessageId()](#validateByMessageId)
- [.validate()](#validate)
- [.schema](#schema)
- [Example usage with .validateByMessageId() method](#example-usage-with-validatebymessageid-method)
- [Example usage with .validate() method](#example-usage-with-validate-method)
- [Errors](#errors)
- [Error Example](#error-example)

## Class Methods

Expand All @@ -33,12 +45,29 @@ AsyncApiValidator.fromSource(source, options)
| value | type | | description |
|-----|----|----|---|
| ignoreArray | boolean | optional | If `true`, then if schema is defined as an array and payload is an object, then payload will be placed inside an array before validation. |
| msgIdentifier | string | required | Name of parameter whose value will be used as `"key"` in `.validate()` method. Recommendation is to use `"name"` as described in [message-object](https://asyncapi.io/docs/specifications/2.0.0/#a-name-messageobject-a-message-object). You can also use [Specification Extensions](https://asyncapi.io/docs/specifications/2.0.0/#specificationExtensions)|
| msgIdentifier | string | optional (required only if you use .validate() method) | Name of the parameter whose value will be used as `"key"` in `.validate()` method. Recommendation is to use `"name"` as described in [message-object](https://asyncapi.io/docs/specifications/2.0.0/#a-name-messageobject-a-message-object). You can also use [Specification Extensions](https://asyncapi.io/docs/specifications/2.0.0/#specificationExtensions). |
| path | string | optional | Path to the AsyncAPI document. It will be used to resolve relative references. Defaults to current working dir. As [used in asyncapi-parser](https://github.com/asyncapi/parser-js/blob/master/lib/parser.js#L41) |

## Instance Methods
## Instance Methods / Properties

### .validateByMessageId()

Here `messageId` should be as [defined in AsyncAPI Schema v2.4.0](https://www.asyncapi.com/docs/specifications/v2.4.0#messageObject). To use this method, your AsyncAPI Schema version should be >= v2.4.0.

```js
/**
* Method to validate the Payload against schema definition.
* @param {string} key - required - messageId
* @param {Object} payload - required - payload of the message
* @returns {boolean}
*/
.validateByMessageId(key, payload)
```

### .validate()

To use this method for validation, you should provide `msgIdentifier` in AsyncApiValidator `options`.

```js
/**
* Method to validate the Payload against schema definition.
Expand All @@ -54,7 +83,41 @@ AsyncApiValidator.fromSource(source, options)
### .schema
`.schema` property can be used to access AsyncAPI schema in JSON format and with all the refs resolved.

## Example usage
## Example usage with .validateByMessageId() method
Schema
```yaml
asyncapi: 2.4.0

info:
title: User Events
version: 1.0.0

channels:
user-events:
description: user related events
publish:
message:
messageId: UserDeletedMessage
payload:
type: object
properties:
userEmail:
type: string
userId:
type: string
```
```js
const AsyncApiValidator = require('asyncapi-validator')
let va = await AsyncApiValidator.fromSource('./api.yaml')

// validate messageId 'UserDeleted'
va.validate('UserDeleted', {
userId: '123456789',
userEmail: '[email protected]',
})
```

## Example usage with .validate() method
Schema
```yaml
asyncapi: 2.0.0
Expand Down Expand Up @@ -97,13 +160,13 @@ Error thrown from asyncapi-validator will have these properties.
|---------|--------|-------------------------|-----------------------------------------------------------------------------------------------------------------|
| name | string | AsyncAPIValidationError | AsyncAPIValidationError |
| key | string | | "key" of payload against which schema is validated |
| message | string | | [errorsText from AJV](https://github.com/epoberezkin/ajv#errorstextarrayobject-errors--object-options---string) |
| errors | array | | [Array of errors from AJV](https://github.com/epoberezkin/ajv#validation-errors) |
| message | string | | [errorsText from AJV](https://ajv.js.org/api.html#ajv-errorstext-errors-object-options-object-string) |
| errors | array | | [Array of errors from AJV](https://ajv.js.org/api.html#validation-errors) |

### Error Example
```js
{
AsyncAPIValidationError: data.type should be equal to one of the allowed values at MessageValidator.validate (.....
AsyncAPIValidationError: data.type must be equal to one of the allowed values at MessageValidator.validate (.....
name: 'AsyncAPIValidationError',
key: 'hello',
errors:
Expand All @@ -112,23 +175,9 @@ Error thrown from asyncapi-validator will have these properties.
dataPath: '.type',
schemaPath: '#/properties/type/enum',
params: [Object],
message: 'should be equal to one of the allowed values'
message: 'must be equal to one of the allowed values'
}
]
}
```
## How it works
asyncapi-validator validates the payload of the messages of a certain message, as described in your schema document. To validate against
a certain message, it needs to find the message are you pointing to in schema document. For that, you need to pass it `key`, `channel`, and `operation` of the message.
```js
validate(key, payload, channel, operation)
```
- One `channel` should be defined only once in your whole schema document.
- The `key` should be unique for an `operation` on a `channel`.
That means,
- Messages going to different operations on one channel, can have same `key`.
- Messages going to different channels, can have same `key`
35 changes: 20 additions & 15 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
declare module 'asyncapi-validator' {
type Validator = {
validate: (
key: string,
payload: unknown,
channel: string,
operation: 'publish' | 'subscribe',
) => boolean;
};

const fromSource: (
path: string | Record<string, unknown>,
options: { msgIdentifier: string; ignoreArray?: boolean },
) => Promise<Validator>;
}
declare module 'asyncapi-validator' {
type Validator = {
validate: (
key: string,
payload: unknown,
channel: string,
operation: 'publish' | 'subscribe',
) => boolean;

validateByMessageId: (
key: string,
payload: unknown,
) => boolean;
};

const fromSource: (
path: string | Record<string, unknown>,
options?: { msgIdentifier?: string; ignoreArray?: boolean, path?: string },
) => Promise<Validator>;
}
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ module.exports = {
// ],

// The regexp pattern or array of patterns that Jest uses to detect test files
testRegex: ['./test/src/*', './test/v2.0.0/*'],
testRegex: ['./test/src/*', './test/v2.*/*'],

// This option allows the use of a custom results processor
// testResultsProcessor: null,
Expand Down
Loading

0 comments on commit 34ef690

Please sign in to comment.