From 43f7070f0f3af401331e22c22c703080498fdb86 Mon Sep 17 00:00:00 2001 From: derberg Date: Wed, 24 Jan 2024 14:15:00 +0100 Subject: [PATCH] chore: adjustments --- definitions/3.0.0/info.json | 121 +++++++++++++------------- definitions/3.0.0/infoExtensions.json | 11 +++ extensions/0.1.0/x.json | 15 ---- extensions/x/0.1.0/schema.json | 10 +++ tools/bundler/index.js | 51 ++++++++--- 5 files changed, 120 insertions(+), 88 deletions(-) create mode 100644 definitions/3.0.0/infoExtensions.json delete mode 100644 extensions/0.1.0/x.json create mode 100644 extensions/x/0.1.0/schema.json diff --git a/definitions/3.0.0/info.json b/definitions/3.0.0/info.json index e3f1462a..034eb5ab 100644 --- a/definitions/3.0.0/info.json +++ b/definitions/3.0.0/info.json @@ -1,69 +1,70 @@ { - "type": "object", "description": "The object provides metadata about the API. The metadata can be used by the clients if needed.", - "required": [ - "version", - "title" - ], - "additionalProperties": false, - "patternProperties": { - "^x-[\\w\\d\\.\\x2d_]+$": { - "$ref": "http://asyncapi.com/definitions/3.0.0/specificationExtension.json" - } - }, - "properties": { - "title": { - "type": "string", - "description": "A unique and precise title of the API." - }, - "version": { - "type": "string", - "description": "A semantic version number of the API." - }, - "description": { - "type": "string", - "description": "A longer description of the API. Should be different from the title. CommonMark is allowed." - }, - "termsOfService": { - "type": "string", - "description": "A URL to the Terms of Service for the API. MUST be in the format of a URL.", - "format": "uri" - }, - "contact": { - "$ref": "http://asyncapi.com/definitions/3.0.0/contact.json" - }, - "license": { - "$ref": "http://asyncapi.com/definitions/3.0.0/license.json" - }, - "tags": { - "type": "array", - "description": "A list of tags for application API documentation control. Tags can be used for logical grouping of applications.", - "items": { - "oneOf": [ - { - "$ref": "http://asyncapi.com/definitions/3.0.0/Reference.json" - }, - { - "$ref": "http://asyncapi.com/definitions/3.0.0/tag.json" - } - ] + "allOf": [ + { + "type": "object", + "required": ["version", "title"], + "additionalProperties": false, + "patternProperties": { + "^x-[\\w\\d\\.\\x2d_]+$": { + "$ref": "http://asyncapi.com/definitions/3.0.0/specificationExtension.json" + } }, - "uniqueItems": true - }, - "externalDocs": { - "oneOf": [ - { - "$ref": "http://asyncapi.com/definitions/3.0.0/Reference.json" + "properties": { + "title": { + "type": "string", + "description": "A unique and precise title of the API." }, - { - "$ref": "http://asyncapi.com/definitions/3.0.0/externalDocs.json" + "version": { + "type": "string", + "description": "A semantic version number of the API." + }, + "description": { + "type": "string", + "description": "A longer description of the API. Should be different from the title. CommonMark is allowed." + }, + "termsOfService": { + "type": "string", + "description": "A URL to the Terms of Service for the API. MUST be in the format of a URL.", + "format": "uri" + }, + "contact": { + "$ref": "http://asyncapi.com/definitions/3.0.0/contact.json" + }, + "license": { + "$ref": "http://asyncapi.com/definitions/3.0.0/license.json" + }, + "tags": { + "type": "array", + "description": "A list of tags for application API documentation control. Tags can be used for logical grouping of applications.", + "items": { + "oneOf": [ + { + "$ref": "http://asyncapi.com/definitions/3.0.0/Reference.json" + }, + { + "$ref": "http://asyncapi.com/definitions/3.0.0/tag.json" + } + ] + }, + "uniqueItems": true + }, + "externalDocs": { + "oneOf": [ + { + "$ref": "http://asyncapi.com/definitions/3.0.0/Reference.json" + }, + { + "$ref": "http://asyncapi.com/definitions/3.0.0/externalDocs.json" + } + ] } - ] + } + }, + { + "$ref": "http://asyncapi.com/definitions/3.0.0/infoExtensions.json" } - }, - "x":{ - "$ref": "http://asyncapi.com/extensions/0.1.0/x.json" - }, + ], "example": { "$ref": "http://asyncapi.com/examples/3.0.0/info.json" }, diff --git a/definitions/3.0.0/infoExtensions.json b/definitions/3.0.0/infoExtensions.json new file mode 100644 index 00000000..12d739ba --- /dev/null +++ b/definitions/3.0.0/infoExtensions.json @@ -0,0 +1,11 @@ +{ + "type": "object", + "description": "The object that lists all the extensions of Info", + "properties": { + "x-x":{ + "$ref": "http://asyncapi.com/extensions/x/0.1.0/schema.json" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://asyncapi.com/definitions/3.0.0/infoExtensions.json" +} \ No newline at end of file diff --git a/extensions/0.1.0/x.json b/extensions/0.1.0/x.json deleted file mode 100644 index eb095c22..00000000 --- a/extensions/0.1.0/x.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "additionalProperties": false, - "properties": { - "x-x": { - "type": "string", - "description": "This extension allows you to provide the Twitter username of the account representing the team/company of the API.", - "example": [ - "sambhavgupta75", - "AsyncAPISpec" - ] - } - }, - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://asyncapi.com/extensions/0.1.0/x.json" -} \ No newline at end of file diff --git a/extensions/x/0.1.0/schema.json b/extensions/x/0.1.0/schema.json new file mode 100644 index 00000000..e3f822a2 --- /dev/null +++ b/extensions/x/0.1.0/schema.json @@ -0,0 +1,10 @@ +{ + "type": "string", + "description": "This extension allows you to provide the Twitter username of the account representing the team/company of the API.", + "example": [ + "sambhavgupta75", + "AsyncAPISpec" + ], + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://asyncapi.com/extensions/x/0.1.0/schema.json" +} \ No newline at end of file diff --git a/tools/bundler/index.js b/tools/bundler/index.js index a3aa9036..2975a20b 100644 --- a/tools/bundler/index.js +++ b/tools/bundler/index.js @@ -18,6 +18,9 @@ const definitionsRegex = /http:\/\/asyncapi\.com\/definitions\/[^/]*\/(.+)\.json // definitionsRegex is used to transform the name of a binding into a valid one to be used in the -without-$id.json files. const bindingsRegex = /http:\/\/asyncapi\.com\/(bindings\/[^/]+)\/([^/]+)\/(.+)\.json(.*)/i +// definitionsRegex is used to transform the name of a binding into a valid one to be used in the -without-$id.json files. +const extensionsRegex = /http:\/\/asyncapi\.com\/(extensions\/[^/]+)\/([^/]+)\/(.+)\.json(.*)/i + /** * Function to load all the core AsyncAPI spec definition (except the root asyncapi schema, as that will be loaded later) into the bundler. */ @@ -25,6 +28,7 @@ async function loadDefinitions(bundler, versionDir) { const definitions = await fs.promises.readdir(versionDir); const definitionFiles = definitions.filter((value) => {return !value.includes('asyncapi')}).map((file) => fs.readFileSync(path.resolve(versionDir, file))); const definitionJson = definitionFiles.map((file) => JSON.parse(file)); + for (const jsonFile of definitionJson) { if (jsonFile.example) { // Replaced the example property with the referenced example property @@ -40,20 +44,36 @@ async function loadDefinitions(bundler, versionDir) { } } } + + /** - * Function to load all the binding version schemas into the bundler + * Function to load all schemas into bundler, by "type" you specify if these are "bindings" or "extensions" */ -async function loadBindings(bundler) { - const bindingDirectories = await fs.promises.readdir(bindingsDirectory); - for (const bindingDirectory of bindingDirectories) { - const bindingVersionDirectories = await fs.promises.readdir(path.resolve(bindingsDirectory, bindingDirectory)); - const bindingVersionDirectoriesFiltered = bindingVersionDirectories.filter((file) => fs.lstatSync(path.resolve(bindingsDirectory, bindingDirectory, file)).isDirectory()); - for (const bindingVersionDirectory of bindingVersionDirectoriesFiltered) { - const bindingFiles = await fs.promises.readdir(path.resolve(bindingsDirectory, bindingDirectory, bindingVersionDirectory)); - const bindingFilesFiltered = bindingFiles.filter((bindingFile) => path.extname(bindingFile) === '.json').map((bindingFile) => path.resolve(bindingsDirectory, bindingDirectory, bindingVersionDirectory, bindingFile)); - for (const bindingFile of bindingFilesFiltered) { - const bindingFileContent = require(bindingFile); - bundler.add(bindingFileContent); +async function loadSchemas(bundler, type) { + + let directory; + + switch (type) { + case "bindings": + directory = bindingsDirectory; + break; + case "extensions": + directory = extensionsDirectory; + break; + default: + console.error("Invalid input. I'm not going to assume if you want bindings or extensions - these are different beasts."); + } + + const directories = await fs.promises.readdir(directory); + for (const nestedDir of directories) { + const versionDirectories = await fs.promises.readdir(path.resolve(directory, nestedDir)); + const versionDirectoriesFiltered = versionDirectories.filter((file) => fs.lstatSync(path.resolve(directory, nestedDir, file)).isDirectory()); + for (const versionDir of versionDirectoriesFiltered) { + const files = await fs.promises.readdir(path.resolve(directory, nestedDir, versionDir)); + const filesFiltered = files.filter((file) => path.extname(file) === '.json').map((file) => path.resolve(directory, nestedDir, versionDir, file)); + for (const filteredFile of filesFiltered) { + const fileContent = require(filteredFile); + bundler.add(fileContent); } } } @@ -76,7 +96,8 @@ async function loadBindings(bundler) { const outputFileWithoutId = path.resolve(outputDirectory, `${version}-without-$id.json`); const versionDir = path.resolve(definitionsDirectory, version); await loadDefinitions(Bundler, versionDir); - await loadBindings(Bundler); + await loadSchemas(Bundler, 'bindings'); + await loadSchemas(Bundler, 'extensions'); const filePathToBundle = `file://${versionDir}/asyncapi.json`; const fileToBundle = await Bundler.get(filePathToBundle); @@ -157,6 +178,10 @@ function getDefinitionName(def) { const result = bindingsRegex.exec(def); if (result) return `${result[1].replace('/', '-')}-${result[2]}-${result[3]}`; } + if (def.startsWith('http://asyncapi.com/extensions')) { + const result = extensionsRegex.exec(def); + if (result) return `${result[1].replace('/', '-')}-${result[2]}-${result[3]}`; + } return path.basename(def, '.json') }