Skip to content

Commit

Permalink
fix support for v3
Browse files Browse the repository at this point in the history
  • Loading branch information
jonaslagoni committed Sep 27, 2023
1 parent b306a17 commit bbc6cb0
Show file tree
Hide file tree
Showing 7 changed files with 648 additions and 583 deletions.
66 changes: 42 additions & 24 deletions lib/generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,18 @@ class Generator {
* console.error(e);
* }
*
* @param {AsyncAPIDocument} asyncapiDocument AsyncAPIDocument object to use as source.
* @param {AsyncAPIDocument | string} asyncapiDocument AsyncAPIDocument object to use as source.
* @param {Object} [parseOptions={}] AsyncAPI Parser parse options. Check out {@link https://www.github.com/asyncapi/parser-js|@asyncapi/parser} for more information. Remember to use the right options to the right parser depending on the template you are using.
* @return {Promise}
*/
async generate(asyncapiDocument) {
if (!isAsyncAPIDocument(asyncapiDocument)) throw new Error('Parameter "asyncapiDocument" must be an AsyncAPIDocument object.');

async generate(asyncapiDocument, parseOptions = {}) {
const isAlreadyParsedDocument = isAsyncAPIDocument(asyncapiDocument);
const isParsableCompatible = asyncapiDocument || typeof asyncapiString === 'string';
if (!isAlreadyParsedDocument && !isParsableCompatible) {
throw new Error('Parameter "asyncapiDocument" must be a non-empty string or an already parsed AsyncAPI document.');
}
this.asyncapi = asyncapiDocument;

if (this.output === 'fs') {
xfs.mkdirpSync(this.targetDir);
if (!this.forceWrite) await this.verifyTargetDir(this.targetDir);
Expand All @@ -176,11 +181,11 @@ class Generator {
this.templateName = templatePkgName;
this.templateContentDir = path.resolve(this.templateDir, TEMPLATE_CONTENT_DIRNAME);
await this.loadTemplateConfig();
validateTemplateConfig(this.templateConfig, this.templateParams, asyncapiDocument);
await this.configureTemplate();

// use the expected document API based on `templateConfig.apiVersion` value
this.asyncapi = asyncapiDocument = getProperApiDocument(asyncapiDocument, this.templateConfig);
await this.parseInput(this.asyncapi, parseOptions);

validateTemplateConfig(this.templateConfig, this.templateParams, this.asyncapi);
await this.configureTemplate();

if (!isReactTemplate(this.templateConfig)) {
await registerFilters(this.nunjucks, this.templateConfig, this.templateDir, FILTERS_DIRNAME);
Expand All @@ -192,17 +197,38 @@ class Generator {
const entrypointPath = path.resolve(this.templateContentDir, this.entrypoint);
if (!(await exists(entrypointPath))) throw new Error(`Template entrypoint "${entrypointPath}" couldn't be found.`);
if (this.output === 'fs') {
await this.generateFile(asyncapiDocument, path.basename(entrypointPath), path.dirname(entrypointPath));
await this.generateFile(this.asyncapi, path.basename(entrypointPath), path.dirname(entrypointPath));
await this.launchHook('generate:after');
} else if (this.output === 'string') {
return this.renderFile(asyncapiDocument, entrypointPath);
return this.renderFile(this.asyncapi, entrypointPath);
}
} else {
await this.generateDirectoryStructure(asyncapiDocument);
await this.generateDirectoryStructure(this.asyncapi);
await this.launchHook('generate:after');
}
}

/**
* Parse the generator input based on the template `templateConfig.apiVersion` value.
*/
async parseInput(asyncapiDocument, parseOptions = {}) {
const isAlreadyParsedDocument = isAsyncAPIDocument(asyncapiDocument);
// use the expected document API based on `templateConfig.apiVersion` value
if (isAlreadyParsedDocument) {
this.asyncapi = getProperApiDocument(asyncapiDocument, this.templateConfig);
} else {
/** @type {AsyncAPIDocument} Parsed AsyncAPI schema. See {@link https://github.com/asyncapi/parser-js/blob/master/API.md#module_@asyncapi/parser+AsyncAPIDocument|AsyncAPIDocument} for details on object structure. */
const { document, diagnostics } = await parse(asyncapiDocument, parseOptions, this);
if (!document) {
const err = new Error('Input is not a correct AsyncAPI document so it cannot be processed.');
err.diagnostics = diagnostics;
throw err;
} else {
this.asyncapi = getProperApiDocument(document, this.templateConfig);
}
}
}

/**
* Configure the templates based the desired renderer.
*/
Expand Down Expand Up @@ -250,22 +276,15 @@ class Generator {
*
* @param {String} asyncapiString AsyncAPI string to use as source.
* @param {Object} [parseOptions={}] AsyncAPI Parser parse options. Check out {@link https://www.github.com/asyncapi/parser-js|@asyncapi/parser} for more information.
* @deprecated Use the `generate` function instead. Just change the function name and it works out of the box.
* @return {Promise}
*/
async generateFromString(asyncapiString, parseOptions = {}) {
if (!asyncapiString || typeof asyncapiString !== 'string') throw new Error('Parameter "asyncapiString" must be a non-empty string.');

/** @type {String} AsyncAPI string to use as a source. */
this.originalAsyncAPI = asyncapiString;

/** @type {AsyncAPIDocument} Parsed AsyncAPI schema. See {@link https://github.com/asyncapi/parser-js/blob/master/API.md#module_@asyncapi/parser+AsyncAPIDocument|AsyncAPIDocument} for details on object structure. */
const { document, diagnostics } = await parse(asyncapiString, parseOptions, this);
if (!document) {
const err = new Error('Input is not a correct AsyncAPI document so it cannot be processed.');
err.diagnostics = diagnostics;
throw err;
const isParsableCompatible = asyncapiString && typeof asyncapiString === 'string';
if (!isParsableCompatible) {
throw new Error('Parameter "asyncapiString" must be a non-empty string.');
}
return this.generate(document);
return this.generate(asyncapiString, parseOptions);
}

/**
Expand Down Expand Up @@ -416,7 +435,6 @@ class Generator {
*/
getAllParameters(asyncapiDocument) {
const parameters = new Map();

if (usesNewAPI(this.templateConfig)) {
asyncapiDocument.channels().all().forEach(channel => {
channel.parameters().all().forEach(parameter => {
Expand Down
4 changes: 2 additions & 2 deletions lib/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ const { ConvertDocumentParserAPIVersion, NewParser } = require('@smoya/multi-par
const parser = module.exports;

/**
* Conver the template defined value `apiVersion: 'v1'` to only contain the numeric value `1`.
* Convert the template defined value `apiVersion: 'v1'` to only contain the numeric value `1`.
*/
parser.sanitizeTemplateApiVersion = (apiVersion) => {
if (apiVersion && apiVersion.length > 1) {
return apiVersion.substring('1');
return apiVersion.substring(1);
}
return apiVersion;
};
Expand Down
27 changes: 17 additions & 10 deletions lib/templateConfigValidator.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ const semver = require('semver');
const Ajv = require('ajv');
const { getGeneratorVersion } = require('./utils');
const levenshtein = require('levenshtein-edit-distance');
// eslint-disable-next-line no-unused-vars
const {AsyncAPIDocumentInterface, AsyncAPIDocument} = require('@asyncapi/parser');
const { usesNewAPI } = require('./parser');

const ajv = new Ajv({ allErrors: true });

Expand All @@ -12,13 +15,13 @@ const supportedParserAPIMajorVersions = [
];

/**
* Validates the template configuration.
*
* @param {Object} templateConfig Template configuration.
* @param {Object} templateParams Params specified when running generator.
* @param {AsyncAPIDocument} asyncapiDocument AsyncAPIDocument object to use as source.
* @return {Boolean}
*/
* Validates the template configuration.
*
* @param {Object} templateConfig Template configuration.
* @param {Object} templateParams Params specified when running generator.
* @param {AsyncAPIDocumentInterface | AsyncAPIDocument} asyncapiDocument AsyncAPIDocument object to use as source.
* @return {Boolean}
*/
module.exports.validateTemplateConfig = (templateConfig, templateParams, asyncapiDocument) => {
const { parameters, supportedProtocols, conditionalFiles, generator, apiVersion } = templateConfig;

Expand All @@ -27,9 +30,13 @@ module.exports.validateTemplateConfig = (templateConfig, templateParams, asyncap
isRequiredParamProvided(parameters, templateParams);
isProvidedTemplateRendererSupported(templateConfig);
if (asyncapiDocument) {
const server = asyncapiDocument.servers().get(templateParams.server);
isServerProvidedInDocument(server, templateParams.server);
isServerProtocolSupported(server, supportedProtocols, templateParams.server);
if (usesNewAPI(templateConfig)) {

} else {
const server = asyncapiDocument.servers().get(templateParams.server);
isServerProvidedInDocument(server, templateParams.server);
isServerProtocolSupported(server, supportedProtocols, templateParams.server);
}
}

isProvidedParameterSupported(parameters, templateParams);
Expand Down
Loading

0 comments on commit bbc6cb0

Please sign in to comment.