Skip to content

Commit

Permalink
feat: add all recommended and must supported schema formats (#365)
Browse files Browse the repository at this point in the history
Co-authored-by: Fran Méndez <fmvilas@gmail.com>
Co-authored-by: Lukasz Gornicki <lpgornicki@gmail.com>
  • Loading branch information
3 people committed Jul 26, 2023
1 parent 9d49396 commit ba244f8
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 7 deletions.
4 changes: 1 addition & 3 deletions definitions/3.0.0/asyncapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
33 changes: 32 additions & 1 deletion definitions/3.0.0/multiFormatSchema.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,44 @@
},
"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": {}
},
"allOf": [
{
"if": {
"not": {
"description": "If no schemaFormat has been defined, default to schema or reference",
"required": [
"schemaFormat"
]
Expand All @@ -47,6 +77,7 @@
},
{
"if": {
"description": "If schemaFormat has been defined check if it's one of the AsyncAPI Schema Object formats",
"required": [
"schemaFormat"
],
Expand Down
70 changes: 67 additions & 3 deletions scripts/add-new-version.js
Original file line number Diff line number Diff line change
@@ -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.
*/
Expand All @@ -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}`;
Expand All @@ -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}`)
}
Expand Down

0 comments on commit ba244f8

Please sign in to comment.