From a471b07de3bf23c649cd3cac114b41d8c36ca3df Mon Sep 17 00:00:00 2001 From: Lukasz Gornicki Date: Wed, 1 Jul 2020 11:47:49 +0200 Subject: [PATCH] feat: registation of parsers without providing mime types (#92) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fran Méndez --- .github/FUNDING.yml | 12 ------------ README.md | 23 +++++++++++++++++++++++ lib/index.js | 21 ++++++++++++--------- lib/parser.js | 18 ++++++++++++------ test/parse_test.js | 24 ++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 27 deletions(-) delete mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 86f7b07cc..000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,12 +0,0 @@ -# These are supported funding model platforms - -github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] -patreon: # Replace with a single Patreon username -open_collective: asyncapi -ko_fi: # Replace with a single Ko-fi username -tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: # Replace with a single Liberapay username -issuehunt: # Replace with a single IssueHunt username -otechie: # Replace with a single Otechie username -custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/README.md b/README.md index 83c48a94f..52e43e10b 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,28 @@ Head over to [asyncapi/openapi-schema-parser](https://www.github.com/asyncapi/op Head over to [asyncapi/raml-dt-schema-parser](https://www.github.com/asyncapi/raml-dt-schema-parser) for more information. +### Custom message parsers + +AsyncAPI doesn't enforce one schema format for messages. You can have payload of your messages described with OpenAPI, Avro, etc. This parser by default parses only AsyncAPI schema format. You can extend it by creating a custom parser and registering it withing the parser: + +1. Create custom parser module that exports two functions: + ```js + module.exports = { + parse: ({ message, defaultSchemaFormat }) => { //custom parsing logic}, + getMimeTypes: () => [ + '//mime types that will be used as the `schemaFormat` property of the message to specify its mime type', + 'application/vnd.custom.type;version=1.0.0', + 'application/vnd.custom.type+json;version=1.0.0', + ] + } + ``` +2. Before parsing an AsyncAPI document with a parser, register the additional custom schema parser: + ``` + const myCustomParser = require('mycustomParser'); + + parser.registerSchemaParser(myCustomParser); + ``` + ### Error types This package throws a bunch of different error types. All errors contain a `type` (prefixed by this repo URL) and a `title` field. The following table describes all the errors and the extra fields they include: @@ -95,6 +117,7 @@ This package throws a bunch of different error types. All errors contain a `type |`dereference-error`|`parsedJSON`, `refs`|This means the parser tried to resolve and dereference $ref's and the process failed. Typically, this means the $ref it's pointing to doesn't exist. |`unexpected-error`|`parsedJSON`|We have our code covered with try/catch blocks and you should never see this error. If you see it, please open an issue to let us know. |`validation-errors`|`parsedJSON`, `validationErrors`|The AsyncAPI document contains errors. See `validationErrors` for more information. +|`impossible-to-register-parser`| None | Registration of custom message parser failed. For more information about the `ParserError` class, [check out the documentation](./API.md#new_ParserError_new). diff --git a/lib/index.js b/lib/index.js index 4fa045760..c73c4ae62 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,14 +1,17 @@ const parser = require('./parser'); -const noop = () => {}; // No operation +const noop = { + parse: () => {}, // No operation + getMimeTypes: () => [ + 'application/vnd.aai.asyncapi;version=2.0.0', + 'application/vnd.aai.asyncapi+json;version=2.0.0', + 'application/vnd.aai.asyncapi+yaml;version=2.0.0', + 'application/schema;version=draft-07', + 'application/schema+json;version=draft-07', + 'application/schema+yaml;version=draft-07', + ] +}; -parser.registerSchemaParser([ - 'application/vnd.aai.asyncapi;version=2.0.0', - 'application/vnd.aai.asyncapi+json;version=2.0.0', - 'application/vnd.aai.asyncapi+yaml;version=2.0.0', - 'application/schema;version=draft-07', - 'application/schema+json;version=draft-07', - 'application/schema+yaml;version=draft-07', -], noop); +parser.registerSchemaParser(noop); module.exports = parser; diff --git a/lib/parser.js b/lib/parser.js index 8ad8c1b7d..ebccdfde4 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -183,13 +183,19 @@ async function validateAndConvertMessage (msg) { * * @name module:Parser#registerSchemaParser * @param {string[]} schemaFormats An array of schema formats the given schema parser is able to recognize and transform. - * @param {Function} parserFunction The schema parser function. + * @param {Object} parserModule The schema parser module containing parse() and getMimeTypes() functions. */ -function registerSchemaParser(schemaFormats, parserFunction) { - if (!Array.isArray(schemaFormats)) throw new ParserError(`schemaFormats must be an array of strings but found ${typeof schemaFormats}.`); - if (typeof parserFunction !== 'function') throw new ParserError(`parserFunction must be a function but found ${typeof parserFunction}.`); - schemaFormats.forEach((schemaFormat) => { - PARSERS[schemaFormat] = parserFunction; +function registerSchemaParser(parserModule) { + if (typeof parserModule !== 'object' + || typeof parserModule.parse !== 'function' + || typeof parserModule.getMimeTypes !== 'function') + throw new ParserError({ + type: 'impossible-to-register-parser', + title: 'parserModule must have parse() and getMimeTypes() functions.' + }); + + parserModule.getMimeTypes().forEach((schemaFormat) => { + PARSERS[schemaFormat] = parserModule.parse; }); } diff --git a/test/parse_test.js b/test/parse_test.js index 57af0a8c6..df997a9c4 100644 --- a/test/parse_test.js +++ b/test/parse_test.js @@ -385,3 +385,27 @@ describe('parse()', function() { }, type, message); }); }); + +describe('registerSchemaParser()', function() { + it('no errors can be thrown', function() { + const parserModule = { + parse: () => {}, + getMimeTypes: () => ['schemaFormat1', 'schemaFormat2'] + }; + + expect(() => parser.registerSchemaParser(parserModule)).to.not.throw(); + }); + + it('should throw error that required functions are missing', function() { + const parserModule = { + parse: () => {} + }; + + try { + parser.registerSchemaParser(parserModule); + } catch (e) { + expect(e.type).to.equal('https://github.com/asyncapi/parser-js/impossible-to-register-parser'); + expect(e.title).to.equal('parserModule must have parse() and getMimeTypes() functions.'); + } + }); +}); \ No newline at end of file