diff --git a/definitions/3.0.0/asyncapi.json b/definitions/3.0.0/asyncapi.json index 0157a6dd..18a6c39d 100644 --- a/definitions/3.0.0/asyncapi.json +++ b/definitions/3.0.0/asyncapi.json @@ -16,9 +16,7 @@ "properties": { "asyncapi": { "type": "string", - "enum": [ - "3.0.0" - ], + "const": "3.0.0", "description": "The AsyncAPI specification version of this document." }, "id": { diff --git a/definitions/3.0.0/multiFormatSchema.json b/definitions/3.0.0/multiFormatSchema.json index 8f91cc05..fa993a10 100644 --- a/definitions/3.0.0/multiFormatSchema.json +++ b/definitions/3.0.0/multiFormatSchema.json @@ -17,7 +17,36 @@ }, "properties": { "schemaFormat": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "description": "All the schema formats tooling MUST support", + "enum": [ + "application/schema+json;version=draft-07", + "application/schema+yaml;version=draft-07", + + "application/vnd.aai.asyncapi;version=3.0.0", + "application/vnd.aai.asyncapi+json;version=3.0.0", + "application/vnd.aai.asyncapi+yaml;version=3.0.0" + ] + }, + { + "description": "All the schema formats tools are RECOMMENDED to support", + "enum": [ + "application/vnd.oai.openapi;version=3.0.0", + "application/vnd.oai.openapi+json;version=3.0.0", + "application/vnd.oai.openapi+yaml;version=3.0.0", + + "application/vnd.apache.avro;version=1.9.0", + "application/vnd.apache.avro+json;version=1.9.0", + "application/vnd.apache.avro+yaml;version=1.9.0", + + "application/raml+yaml;version=1.0" + ] + } + ] }, "schema": {} }, @@ -25,6 +54,7 @@ { "if": { "not": { + "description": "If no schemaFormat has been defined, default to schema or reference", "required": [ "schemaFormat" ] @@ -47,6 +77,7 @@ }, { "if": { + "description": "If schemaFormat has been defined check if it's one of the AsyncAPI Schema Object formats", "required": [ "schemaFormat" ], diff --git a/scripts/add-new-version.js b/scripts/add-new-version.js index 947c5df3..6cdeaf8f 100644 --- a/scripts/add-new-version.js +++ b/scripts/add-new-version.js @@ -1,3 +1,4 @@ +const path = require('path'); /** * This script adds a new version of the spec with examples, by copying the latest one as baseline. */ @@ -23,6 +24,63 @@ function execute(command) { }); } +/** + * Add the new AsyncAPI schema object as values to schemaFormat + * + * If a major version change, replaces all old AsyncAPI schemaFormat values with fresh ones + * if minor or fix, it add new ones + */ +function addNewSchemaVersion(newVersion, newVersionDir, latestVersion) { + const newSchemaFormats = [ + `application/vnd.aai.asyncapi;version=${newVersion}`, + `application/vnd.aai.asyncapi+json;version=${newVersion}`, + `application/vnd.aai.asyncapi+yaml;version=${newVersion}` + ]; + //Did the major version (first char) change from last to new version? + const isMajorVersionChange = newVersion.charAt(0) !== latestVersion.charAt(0); + const objFile = path.resolve(newVersionDir, 'multiFormatSchema.json'); + const obj = require(objFile); + + // Adapt all the MUST supported schema formats + let mustSupportedSchemaFormats = [] = obj?.else?.properties?.schemaFormat?.anyOf[1]?.enum; + + //Add new version to the list of available schemaFormat values + if(mustSupportedSchemaFormats) { + if(isMajorVersionChange) { + //Remove all old AsyncAPI schema formats because we want a clean slate + mustSupportedSchemaFormats = mustSupportedSchemaFormats.filter((format) => !format.includes('application/vnd.aai.asyncapi')); + } + //Add new schema formats + mustSupportedSchemaFormats.push(...newSchemaFormats); + obj.else.properties.schemaFormat.anyOf[1].enum = mustSupportedSchemaFormats; + } else { + throw new Error("Could not find object to add schemaFormat values to"); + } + + //Make sure new versions apply the right schema + let enumsForValidatingSchema = [] = obj?.else?.allOf[1]?.if?.properties?.schemaFormat?.enum; + if(enumsForValidatingSchema) { + //Add new schema formats + enumsForValidatingSchema.push(...newSchemaFormats); + obj.else.allOf[1].if.properties.schemaFormat.enum = enumsForValidatingSchema; + } else { + throw new Error("Could not find location for schemaFormats that applies the AsyncAPI Schema object to the schema property"); + } + + fs.writeFileSync(objFile, JSON.stringify(obj, null, 2)); +} + +/** + * Adapt the root title and .asyncapi property + */ +function adaptRootObject(newVersion, newVersionDir) { + const objFile = path.resolve(newVersionDir, 'asyncapi.json'); + const obj = require(objFile); + obj.title = `AsyncAPI ${newVersion} schema.`; + obj.properties.asyncapi.const = newVersion; + fs.writeFileSync(objFile, JSON.stringify(obj, null, 2)); +} + async function addNewVersion(newVersion) { const newVersionDir = `./definitions/${newVersion}`; const newExampleVersionDir = `./examples/${newVersion}`; @@ -38,11 +96,17 @@ async function addNewVersion(newVersion) { await execute(`cp -R ./definitions/${latestVersion} ${newVersionDir}`); const latestExampleVersion = (await execute('ls -d ./examples/* | sort -V -r | head -1 | xargs -n 1 basename')).trim(); - await execute(`cp -R ./definitions/${latestVersion} ${newVersionDir}`); await execute(`cp -R ./examples/${latestExampleVersion} ${newExampleVersionDir}`); - // Replace old version numbers with new - await execute(`find ${newVersionDir} -name '*.json' -exec sed -i '' "s+${latestVersion}+${newVersion}+g" {} +`); + // Replace $ref and $id paths such as `/3.0.0/` with new version (http://asyncapi.com/definitions/3.0.0/specificationExtension.json) + await execute(`find ${newVersionDir} -name '*.json' -exec sed -i '' \"s+\/${latestVersion}\/+\/${newVersion}\/+g\" {} +`); + + // Replace .asyncapi version from old to new version + // Replace old version in title with new version + adaptRootObject(newVersion, newVersionDir); + + // Add new schemaFormat version entries + addNewSchemaVersion(newVersion, newVersionDir, latestVersion); console.log(`New version added to ${newVersionDir}`) }