Skip to content

Commit

Permalink
fix: id's from AsyncAPI parser was not preserved (#100)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonaslagoni authored Feb 24, 2021
1 parent 7aaa87d commit 1d60ac1
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 58 deletions.
1 change: 1 addition & 0 deletions src/processors/AbstractInputProcessor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { CommonInputModel } from '../models/CommonInputModel';

export abstract class AbstractInputProcessor {
public static MODELGEN_INFFERED_NAME = 'x-modelgen-inferred-name';
// Process content
abstract process(input: any): Promise<CommonInputModel>;
abstract shouldProcess(input: any): boolean;
Expand Down
103 changes: 101 additions & 2 deletions src/processors/AsyncAPIInputProcessor.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {parse, AsyncAPIDocument} from '@asyncapi/parser';
import {parse, AsyncAPIDocument, Schema as AsyncAPISchema} from '@asyncapi/parser';

import { AbstractInputProcessor } from './AbstractInputProcessor';
import { JsonSchemaInputProcessor } from './JsonSchemaInputProcessor';
import { CommonInputModel } from '../models/CommonInputModel';
import { Schema } from '../models/Schema';

export class AsyncAPIInputProcessor extends AbstractInputProcessor {
/**
Expand All @@ -21,13 +22,111 @@ export class AsyncAPIInputProcessor extends AbstractInputProcessor {
}
common.originalInput = doc;
doc.allMessages().forEach((message) => {
const schema = JsonSchemaInputProcessor.reflectSchemaNames(message.payload().json());
const schema = AsyncAPIInputProcessor.reflectSchemaNames(message.payload());
const commonModels = JsonSchemaInputProcessor.convertSchemaToCommonModel(schema);
common.models = {...common.models, ...commonModels};
});
return common;
}

/**
*
* Reflect the name of the schema and save it to `x-modelgen-inferred-name` extension.
* This keeps the the id of the model deterministic if used in conjunction with other AsyncAPI tools such as the generator.
*
* @param schema to reflect name for
*/
// eslint-disable-next-line sonarjs/cognitive-complexity
static reflectSchemaNames(
schema: AsyncAPISchema | boolean
): Schema | boolean {
if (typeof schema === 'boolean') return schema;
let convertedSchema = new Schema();
convertedSchema = Object.assign({}, schema.json());
convertedSchema[this.MODELGEN_INFFERED_NAME] = schema.uid();

if (schema.allOf() !== null) {
convertedSchema.allOf = schema.allOf().map((item) => this.reflectSchemaNames(item));
}
if (schema.oneOf() !== null) {
convertedSchema.oneOf = schema.oneOf().map((item) => this.reflectSchemaNames(item));
}
if (schema.anyOf() !== null) {
convertedSchema.anyOf = schema.anyOf().map((item) => this.reflectSchemaNames(item));
}
if (schema.not() !== null) {
convertedSchema.not = this.reflectSchemaNames(schema.not());
}
if (
typeof schema.additionalItems() === 'object' &&
schema.additionalItems() !== null
) {
convertedSchema.additionalItems = this.reflectSchemaNames(schema.additionalItems());
}
if (schema.contains() !== null) {
convertedSchema.contains = this.reflectSchemaNames(schema.contains());
}
if (schema.propertyNames() !== null) {
convertedSchema.propertyNames = this.reflectSchemaNames(schema.propertyNames());
}
if (schema.if() !== null) {
convertedSchema.if = this.reflectSchemaNames(schema.if());
}
if (schema.then() !== null) {
convertedSchema.then = this.reflectSchemaNames(schema.then());
}
if (schema.else() !== null) {
convertedSchema.else = this.reflectSchemaNames(schema.else());
}
if (
typeof schema.additionalProperties() === 'object' &&
schema.additionalProperties() !== null
) {
convertedSchema.additionalProperties = this.reflectSchemaNames(schema.additionalProperties());
}
if (schema.items() !== null) {
if (Array.isArray(schema.items())) {
convertedSchema.items = (schema.items() as AsyncAPISchema[]).map((item) => this.reflectSchemaNames(item));
} else {
convertedSchema.items = this.reflectSchemaNames(schema.items() as AsyncAPISchema);
}
}

if (schema.properties !== null && Object.keys(schema.properties).length) {
const properties : {[key: string]: Schema | boolean} = {};
Object.entries(schema.properties).forEach(([propertyName, propertySchema]) => {
properties[`${propertyName}`] = this.reflectSchemaNames(propertySchema);
});
convertedSchema.properties = properties;
}
if (schema.dependencies !== null && Object.keys(schema.dependencies).length) {
const dependencies: { [key: string]: Schema | boolean | string[] } = {};
Object.entries(schema.dependencies).forEach(([dependencyName, dependency]) => {
if (typeof dependency === 'object' && !Array.isArray(dependency)) {
dependencies[`${dependencyName}`] = this.reflectSchemaNames(dependency);
} else {
dependencies[`${dependencyName}`] = dependency as string[];
}
});
convertedSchema.dependencies = dependencies;
}
if (schema.patternProperties !== null && Object.keys(schema.patternProperties).length) {
const patternProperties: { [key: string]: Schema | boolean } = {};
Object.entries(schema.patternProperties).forEach(([patternPropertyName, patternProperty]) => {
patternProperties[`${patternPropertyName}`] = this.reflectSchemaNames(patternProperty);
});
convertedSchema.patternProperties = patternProperties;
}
if (schema.definitions !== null && Object.keys(schema.definitions).length) {
const definitions: { [key: string]: Schema | boolean } = {};
Object.entries(schema.definitions).forEach(([definitionName, definition]) => {
definitions[`${definitionName}`] = this.reflectSchemaNames(definition);
});
convertedSchema.definitions = definitions;
}

return convertedSchema;
}
/**
* Figures out if an object is of type AsyncAPI document
*
Expand Down
2 changes: 0 additions & 2 deletions src/processors/JsonSchemaInputProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import path from 'path';
* Class for processing JSON Schema
*/
export class JsonSchemaInputProcessor extends AbstractInputProcessor {
private static MODELGEN_INFFERED_NAME = 'x-modelgen-inferred-name';

/**
* Function for processing a JSON Schema input.
*
Expand Down
109 changes: 55 additions & 54 deletions test/processors/AsyncAPIInputProcessor/commonInputModel/basic.json
Original file line number Diff line number Diff line change
@@ -1,34 +1,33 @@
{
"models": {
"anonymSchema1": {
"originalSchema": {
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email",
"x-parser-schema-id": "<anonymous-schema-2>",
"x-modelgen-inferred-name": "email"
"models":{
"<anonymous-schema-1>":{
"originalSchema":{
"type":"object",
"properties":{
"email":{
"type":"string",
"format":"email",
"x-parser-schema-id":"<anonymous-schema-2>"
}
},
"x-parser-schema-id": "<anonymous-schema-1>"
"x-parser-schema-id":"<anonymous-schema-1>",
"x-modelgen-inferred-name":"<anonymous-schema-1>"
},
"type": "object",
"$id": "anonymSchema1",
"properties": {
"email": {
"originalSchema": {
"type": "string",
"format": "email",
"x-modelgen-inferred-name": "email",
"x-parser-schema-id": "<anonymous-schema-2>"
"type":"object",
"$id":"<anonymous-schema-1>",
"properties":{
"email":{
"originalSchema":{
"type":"string",
"format":"email",
"x-parser-schema-id":"<anonymous-schema-2>"
},
"type": "string"
"type":"string"
}
},
"additionalProperties": {
"originalSchema": true,
"type": [
"additionalProperties":{
"originalSchema":true,
"type":[
"object",
"string",
"number",
Expand All @@ -39,46 +38,48 @@
}
}
},
"customizations": {},
"originalInput": {
"_json": {
"asyncapi": "2.0.0",
"defaultContentType": "application/json",
"externalDocs": {
"description": "Find more info here",
"url": "https://example.com"
"customizations":{

},
"originalInput":{
"_json":{
"asyncapi":"2.0.0",
"defaultContentType":"application/json",
"externalDocs":{
"description":"Find more info here",
"url":"https://example.com"
},
"tags": [
"tags":[
{
"name": "user",
"description": "user signed up"
"name":"user",
"description":"user signed up"
},
{
"name": "signup"
"name":"signup"
}
],
"info": {
"title": "Signup service example (internal)",
"version": "0.1.0"
"info":{
"title":"Signup service example (internal)",
"version":"0.1.0"
},
"channels": {
"/user/signedup": {
"subscribe": {
"message": {
"payload": {
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email",
"x-parser-schema-id": "<anonymous-schema-2>"
"channels":{
"/user/signedup":{
"subscribe":{
"message":{
"payload":{
"type":"object",
"properties":{
"email":{
"type":"string",
"format":"email",
"x-parser-schema-id":"<anonymous-schema-2>"
}
},
"x-parser-schema-id": "<anonymous-schema-1>"
"x-parser-schema-id":"<anonymous-schema-1>"
},
"schemaFormat": "application/vnd.aai.asyncapi;version=2.0.0",
"x-parser-message-parsed": true,
"x-parser-message-name": "<anonymous-message-1>"
"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0",
"x-parser-message-parsed":true,
"x-parser-message-name":"<anonymous-message-1>"
}
}
}
Expand Down

0 comments on commit 1d60ac1

Please sign in to comment.