@asyncapi/avro-schema-parser
Advanced tools
Comparing version 0.3.0 to 0.4.0
{ | ||
"name": "@asyncapi/avro-schema-parser", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"description": "An AsyncAPI schema parser for Avro 1.x schemas.", | ||
@@ -33,3 +33,3 @@ "main": "index.js", | ||
"devDependencies": { | ||
"@asyncapi/parser": "^1.6.0", | ||
"@asyncapi/parser": "^1.8.1", | ||
"@semantic-release/commit-analyzer": "^8.0.1", | ||
@@ -36,0 +36,0 @@ "@semantic-release/github": "^7.0.4", |
@@ -31,2 +31,4 @@ # Avro Schema Parser | ||
type: record | ||
name: User | ||
namespace: com.company | ||
doc: User information | ||
@@ -140,2 +142,10 @@ fields: | ||
### Support for names and namespaces | ||
If, at the top level of the Avro schema, the 'name' attribute is defined, it will be copied to the corresponding JSON schema's 'x-parser-schema-id' attribute. If the Avro schema also has the 'namespace' attribute defined, then that schema's fully qualified name will be put into that attribute. The fully qualified name is defined by the namespace, followed by a dot, followed by the name. | ||
If there are two schemas that resolve to the same fully qualified name, only the last one will be returned by the parser. Make sure names of your schemas are unique. | ||
If no name attribute is present, the 'x-parser-schema-id' will have a generated unique id with a name like 'anonymous-schema-1' generated by the main parser. 'x-parser-schema-id' is one of the [custom extensions](https://github.com/asyncapi/parser-js/#custom-extensions) supported by the parser. | ||
## Limitations | ||
@@ -142,0 +152,0 @@ |
@@ -6,7 +6,10 @@ const fs = require('fs'); | ||
const inputWithAvro182 = fs.readFileSync(path.resolve(__dirname, './asyncapi-avro-1.8.2.yaml'), 'utf8'); | ||
const outputWithAvro182 = '{"asyncapi":"2.0.0","info":{"title":"My API","version":"1.0.0"},"channels":{"mychannel":{"publish":{"message":{"payload":{"type":"object","properties":{"name":{"type":"string","examples":["Donkey"],"x-parser-schema-id":"<anonymous-schema-2>"},"age":{"oneOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647,"x-parser-schema-id":"<anonymous-schema-4>"},{"type":"null","x-parser-schema-id":"<anonymous-schema-5>"}],"default":null,"x-parser-schema-id":"<anonymous-schema-3>"},"favoriteProgrammingLanguage":{"type":"string","enum":["JS","Java","Go","Rust","C"],"x-parser-schema-id":"<anonymous-schema-6>"},"address":{"type":"object","properties":{"zipcode":{"type":"integer","minimum":-2147483648,"maximum":2147483647,"examples":[53003],"x-parser-schema-id":"<anonymous-schema-8>"}},"x-parser-schema-id":"<anonymous-schema-7>"}},"x-parser-schema-id":"<anonymous-schema-1>"},"x-parser-original-schema-format":"application/vnd.apache.avro;version=1.8.2","x-parser-original-payload":{"type":"record","fields":[{"name":"name","type":"string","example":"Donkey"},{"name":"age","type":["null","int"],"default":null},{"name":"favoriteProgrammingLanguage","type":{"name":"ProgrammingLanguage","type":"enum","symbols":["JS","Java","Go","Rust","C"]}},{"name":"address","type":{"name":"Address","type":"record","fields":[{"name":"zipcode","type":"int","example":"53003"}]}}]},"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0","x-parser-message-parsed":true,"x-parser-message-name":"<anonymous-message-1>"}}}},"x-parser-spec-parsed":true}'; | ||
const inputWithAvro190 = fs.readFileSync(path.resolve(__dirname, './asyncapi-avro-1.9.0.yaml'), 'utf8'); | ||
const outputWithAvro190 = '{"asyncapi":"2.0.0","info":{"title":"My API","version":"1.0.0"},"channels":{"mychannel":{"publish":{"message":{"payload":{"type":"object","properties":{"name":{"type":"string","examples":["Donkey"],"x-parser-schema-id":"<anonymous-schema-2>"},"age":{"oneOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647,"examples":[123],"x-parser-schema-id":"<anonymous-schema-4>"},{"type":"null","x-parser-schema-id":"<anonymous-schema-5>"}],"default":null,"x-parser-schema-id":"<anonymous-schema-3>"},"favoriteProgrammingLanguage":{"type":"string","enum":["JS","Java","Go","Rust","C"],"default":"JS","x-parser-schema-id":"<anonymous-schema-6>"},"address":{"type":"object","properties":{"zipcode":{"type":"integer","minimum":-2147483648,"maximum":2147483647,"examples":[53003],"x-parser-schema-id":"<anonymous-schema-8>"}},"x-parser-schema-id":"<anonymous-schema-7>"},"someid":{"type":"string","x-parser-schema-id":"<anonymous-schema-9>"}},"x-parser-schema-id":"<anonymous-schema-1>"},"x-parser-original-schema-format":"application/vnd.apache.avro;version=1.9.0","x-parser-original-payload":{"name":"Person","type":"record","fields":[{"name":"name","type":"string","example":"Donkey"},{"name":"age","type":["null","int"],"default":null,"example":"123"},{"name":"favoriteProgrammingLanguage","type":{"name":"ProgrammingLanguage","type":"enum","symbols":["JS","Java","Go","Rust","C"],"default":"JS"}},{"name":"address","type":{"name":"Address","type":"record","fields":[{"name":"zipcode","type":"int","example":"53003"}]}},{"name":"someid","type":"uuid"}]},"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0","x-parser-message-parsed":true,"x-parser-message-name":"<anonymous-message-1>"}}}},"x-parser-spec-parsed":true}'; | ||
const outputWithAvro190 = '{"asyncapi":"2.0.0","info":{"title":"My API","version":"1.0.0"},"channels":{"mychannel":{"publish":{"message":{"payload":{"type":"object","properties":{"name":{"type":"string","examples":["Donkey"],"x-parser-schema-id":"<anonymous-schema-1>"},"age":{"oneOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647,"examples":[123],"x-parser-schema-id":"<anonymous-schema-3>"},{"type":"null","x-parser-schema-id":"<anonymous-schema-4>"}],"default":null,"x-parser-schema-id":"<anonymous-schema-2>"},"favoriteProgrammingLanguage":{"type":"string","enum":["JS","Java","Go","Rust","C"],"default":"JS","x-parser-schema-id":"<anonymous-schema-5>"},"address":{"type":"object","properties":{"zipcode":{"type":"integer","minimum":-2147483648,"maximum":2147483647,"examples":[53003],"x-parser-schema-id":"<anonymous-schema-7>"}},"x-parser-schema-id":"<anonymous-schema-6>"},"someid":{"type":"string","x-parser-schema-id":"<anonymous-schema-8>"}},"x-parser-schema-id":"Person"},"x-parser-original-schema-format":"application/vnd.apache.avro;version=1.9.0","x-parser-original-payload":{"name":"Person","type":"record","fields":[{"name":"name","type":"string","example":"Donkey"},{"name":"age","type":["null","int"],"default":null,"example":"123"},{"name":"favoriteProgrammingLanguage","type":{"name":"ProgrammingLanguage","type":"enum","symbols":["JS","Java","Go","Rust","C"],"default":"JS"}},{"name":"address","type":{"name":"Address","type":"record","fields":[{"name":"zipcode","type":"int","example":"53003"}]}},{"name":"someid","type":"uuid"}]},"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0","x-parser-message-parsed":true,"x-parser-message-name":"<anonymous-message-1>"}}}},"x-parser-spec-parsed":true}'; | ||
const inputWithAvro182 = fs.readFileSync(path.resolve(__dirname, './asyncapi-avro-1.8.2.yaml'), 'utf8'); | ||
const outputWithAvro182 = '{"asyncapi":"2.0.0","info":{"title":"My API","version":"1.0.0"},"channels":{"mychannel":{"publish":{"message":{"payload":{"type":"object","properties":{"name":{"type":"string","examples":["Donkey"],"x-parser-schema-id":"<anonymous-schema-2>"},"age":{"oneOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647,"x-parser-schema-id":"<anonymous-schema-4>"},{"type":"null","x-parser-schema-id":"<anonymous-schema-5>"}],"default":null,"x-parser-schema-id":"<anonymous-schema-3>"},"favoriteProgrammingLanguage":{"type":"string","enum":["JS","Java","Go","Rust","C"],"x-parser-schema-id":"<anonymous-schema-6>"},"address":{"type":"object","properties":{"zipcode":{"type":"integer","minimum":-2147483648,"maximum":2147483647,"examples":[53003],"x-parser-schema-id":"<anonymous-schema-8>"}},"x-parser-schema-id":"<anonymous-schema-7>"}},"x-parser-schema-id":"<anonymous-schema-1>"},"x-parser-original-schema-format":"application/vnd.apache.avro;version=1.8.2","x-parser-original-payload":{"name":"Person","type":"record","fields":[{"name":"name","type":"string","example":"Donkey"},{"name":"age","type":["null","int"],"default":null},{"name":"favoriteProgrammingLanguage","type":{"name":"ProgrammingLanguage","type":"enum","symbols":["JS","Java","Go","Rust","C"]}},{"name":"address","type":{"name":"Address","type":"record","fields":[{"name":"zipcode","type":"int","example":"53003"}]}}]},"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0","x-parser-message-parsed":true,"x-parser-message-name":"<anonymous-message-1>"}}}},"x-parser-spec-parsed":true}'; | ||
const inputWithAvro190WithNamespace = fs.readFileSync(path.resolve(__dirname, './asyncapi-avro-1.9.0-namespace.yaml'), 'utf8'); | ||
const outputWithAvro190ithNamespace = '{"asyncapi":"2.0.0","info":{"title":"My API","version":"1.0.0"},"channels":{"mychannel":{"publish":{"message":{"payload":{"type":"object","properties":{"name":{"type":"string","examples":["Donkey"],"x-parser-schema-id":"<anonymous-schema-1>"},"age":{"oneOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647,"examples":[123],"x-parser-schema-id":"<anonymous-schema-3>"},{"type":"null","x-parser-schema-id":"<anonymous-schema-4>"}],"default":null,"x-parser-schema-id":"<anonymous-schema-2>"},"favoriteProgrammingLanguage":{"type":"string","enum":["JS","Java","Go","Rust","C"],"default":"JS","x-parser-schema-id":"<anonymous-schema-5>"},"address":{"type":"object","properties":{"zipcode":{"type":"integer","minimum":-2147483648,"maximum":2147483647,"examples":[53003],"x-parser-schema-id":"<anonymous-schema-7>"}},"x-parser-schema-id":"<anonymous-schema-6>"},"someid":{"type":"string","x-parser-schema-id":"<anonymous-schema-8>"}},"x-parser-schema-id":"com.company.Person"},"x-parser-original-schema-format":"application/vnd.apache.avro;version=1.9.0","x-parser-original-payload":{"name":"Person","namespace":"com.company","type":"record","fields":[{"name":"name","type":"string","example":"Donkey"},{"name":"age","type":["null","int"],"default":null,"example":"123"},{"name":"favoriteProgrammingLanguage","type":{"name":"ProgrammingLanguage","type":"enum","symbols":["JS","Java","Go","Rust","C"],"default":"JS"}},{"name":"address","type":{"name":"Address","type":"record","fields":[{"name":"zipcode","type":"int","example":"53003"}]}},{"name":"someid","type":"uuid"}]},"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0","x-parser-message-parsed":true,"x-parser-message-name":"<anonymous-message-1>"}}}},"x-parser-spec-parsed":true}'; | ||
@@ -16,2 +19,6 @@ parser.registerSchemaParser(avroSchemaParser); | ||
describe('parse()', function() { | ||
it('should parse Avro schema 1.8.2', async function() { | ||
const result = await parser.parse(inputWithAvro182, { path: __filename }); | ||
expect(JSON.stringify(result.json())).toEqual(outputWithAvro182); | ||
}); | ||
it('should parse Avro schema 1.9.0', async function() { | ||
@@ -21,6 +28,6 @@ const result = await parser.parse(inputWithAvro190, { path: __filename }); | ||
}); | ||
it('should parse Avro schema 1.8.2', async function() { | ||
const result = await parser.parse(inputWithAvro182, { path: __filename }); | ||
expect(JSON.stringify(result.json())).toEqual(outputWithAvro182); | ||
it('should parse Avro schema 1.9.0 with a namespace', async function() { | ||
const result = await parser.parse(inputWithAvro190WithNamespace, { path: __filename }); | ||
expect(JSON.stringify(result.json())).toEqual(outputWithAvro190ithNamespace); | ||
}); | ||
}); |
@@ -84,2 +84,3 @@ const { avroToJsonSchema } = require('../to-json-schema'); | ||
doc: 'My test record', | ||
name: 'MyName', | ||
fields: [ | ||
@@ -92,2 +93,3 @@ { name: 'key1', type: 'long', doc: 'Key1 docs' }, | ||
type: 'object', | ||
'x-parser-schema-id': 'MyName', | ||
description: 'My test record', | ||
@@ -94,0 +96,0 @@ properties: { |
@@ -24,7 +24,26 @@ const BYTES_PATTERN = '^[\u0000-\u00ff]*$'; | ||
const commonAttributesMapping = (avroDefinition, jsonSchema) => { | ||
const commonAttributesMapping = (avroDefinition, jsonSchema, isTopLevel) => { | ||
if (avroDefinition.doc) jsonSchema.description = avroDefinition.doc; | ||
if (avroDefinition.default !== undefined) jsonSchema.default = avroDefinition.default; | ||
const fullyQualifiedName = getFullyQualifiedName(avroDefinition); | ||
if (isTopLevel && fullyQualifiedName !== undefined) { | ||
jsonSchema['x-parser-schema-id'] = fullyQualifiedName; | ||
} | ||
}; | ||
function getFullyQualifiedName(avroDefinition) { | ||
let name; | ||
if (avroDefinition.name) { | ||
if (avroDefinition.namespace) { | ||
name = `${avroDefinition.namespace}.${avroDefinition.name}`; | ||
} else { | ||
name = avroDefinition.name; | ||
} | ||
} | ||
return name; | ||
} | ||
const exampleAttributeMapping = (typeInput, example, jsonSchemaInput) => { | ||
@@ -55,3 +74,3 @@ let type = typeInput; | ||
module.exports.avroToJsonSchema = async function avroToJsonSchema(avroDefinition) { | ||
async function convertAvroToJsonSchema(avroDefinition, isTopLevel) { | ||
const jsonSchema = {}; | ||
@@ -64,3 +83,3 @@ const isUnion = Array.isArray(avroDefinition); | ||
for (const avroDef of avroDefinition) { | ||
const def = await avroToJsonSchema(avroDef); | ||
const def = await convertAvroToJsonSchema(avroDef, isTopLevel); | ||
// avroDef can be { type: 'int', default: 1 } and this is why avroDef.type has priority here | ||
@@ -100,6 +119,6 @@ const defType = avroDef.type || avroDef; | ||
case 'map': | ||
jsonSchema.additionalProperties = await avroToJsonSchema(avroDefinition.values); | ||
jsonSchema.additionalProperties = await convertAvroToJsonSchema(avroDefinition.values, false); | ||
break; | ||
case 'array': | ||
jsonSchema.items = await avroToJsonSchema(avroDefinition.items); | ||
jsonSchema.items = await convertAvroToJsonSchema(avroDefinition.items, false); | ||
break; | ||
@@ -112,5 +131,5 @@ case 'enum': | ||
for (const field of avroDefinition.fields) { | ||
const def = await avroToJsonSchema(field.type); | ||
const def = await convertAvroToJsonSchema(field.type, false); | ||
commonAttributesMapping(field, def); | ||
commonAttributesMapping(field, def, false); | ||
exampleAttributeMapping(field.type, field.example, def); | ||
@@ -124,6 +143,10 @@ | ||
commonAttributesMapping(avroDefinition, jsonSchema); | ||
commonAttributesMapping(avroDefinition, jsonSchema, isTopLevel); | ||
exampleAttributeMapping(type, avroDefinition.example, jsonSchema); | ||
return jsonSchema; | ||
}; | ||
} | ||
module.exports.avroToJsonSchema = async function avroToJsonSchema(avroDefinition) { | ||
return convertAvroToJsonSchema(avroDefinition, true); | ||
}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
195443
30
294
158
4