Skip to content

Commit 357cde4

Browse files
feat: import objects referenced using avro namespaces (#246)
* package and import files that are in a different namespace * update eslint to support optional chaining * moved stripPackageName function to scsLib
1 parent c48bc1b commit 357cde4

11 files changed

+1352
-1811
lines changed

.eslintrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ env:
44
jest/globals: true
55

66
parserOptions:
7-
ecmaVersion: 2018
7+
ecmaVersion: 2020
88

99
plugins:
1010
- jest

filters/all.js

+46-1
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,50 @@ function stringify(obj) {
539539
}
540540
filter.stringify = stringify;
541541

542+
function extraImports([asyncapi, params]) {
543+
return getExtraImports(asyncapi);
544+
}
545+
filter.extraImports = extraImports;
546+
547+
function getExtraImports(asyncapi) {
548+
const schemaImports = [];
549+
const channelOperationInfos = [];
550+
for (const channelName in asyncapi.channels()) {
551+
const channel = asyncapi.channels()[channelName];
552+
if (channel.hasPublish()) {
553+
channelOperationInfos.push(channel.publish());
554+
}
555+
if (channel.hasSubscribe()) {
556+
channelOperationInfos.push(channel.subscribe());
557+
}
558+
}
559+
if (channelOperationInfos.length > 0) {
560+
channelOperationInfos.forEach(channelOperationInfo => {
561+
const fullPackagePath = getPayloadPackage(channelOperationInfo);
562+
if (fullPackagePath) {
563+
schemaImports.push(fullPackagePath);
564+
}
565+
});
566+
}
567+
return schemaImports;
568+
}
569+
570+
function getPayloadPackage(pubOrSub) {
571+
let fullPackagePath;
572+
if (!pubOrSub.hasMultipleMessages()) {
573+
const payload = pubOrSub.message()?.payload();
574+
if (payload) {
575+
const type = payload.type();
576+
const importName = payload.ext('x-parser-schema-id');
577+
// This is a schema within a package - like an avro schema in a namespace. We're hoping the full thing is part of the x-schema-parser-id.
578+
if ((!type || type === 'object') && importName.includes('.')) {
579+
fullPackagePath = importName;
580+
}
581+
}
582+
}
583+
return fullPackagePath;
584+
}
585+
542586
// Returns true if any property names will be different between json and java.
543587
function checkPropertyNames(name, schema) {
544588
const ret = false;
@@ -896,7 +940,8 @@ function getMessagePayloadType(message) {
896940

897941
if (!type || type === 'object') {
898942
ret = payload.ext('x-parser-schema-id');
899-
ret = _.camelCase(ret);
943+
const { className } = scsLib.stripPackageName(ret);
944+
ret = _.camelCase(className);
900945
ret = _.upperFirst(ret);
901946
} else {
902947
ret = getType(type, payload.format()).javaType;

lib/applicationModel.js

+3-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
const ModelClass = require('./modelClass.js');
22
const debugApplicationModel = require('debug')('applicationModel');
33
const _ = require('lodash');
4+
const ScsLib = require('./scsLib.js');
5+
const scsLib = new ScsLib();
46
const instanceMap = new Map();
57

68
class ApplicationModel {
@@ -156,7 +158,7 @@ class ApplicationModel {
156158
modelClass.setCanBeInnerClass(false);
157159
}
158160

159-
const { className, javaPackage } = this.stripPackageName(schemaName);
161+
const { className, javaPackage } = scsLib.stripPackageName(schemaName);
160162
modelClass.setJavaPackage(javaPackage);
161163
modelClass.setClassName(className);
162164
debugApplicationModel(`schemaName ${schemaName} className: ${modelClass.getClassName()} super: ${modelClass.getSuperClassName()} javaPackage: ${javaPackage}`);
@@ -186,15 +188,6 @@ class ApplicationModel {
186188
return schemaName;
187189
}
188190

189-
stripPackageName(schemaName) {
190-
// If there is a dot in the schema name, it's probably an Avro schema with a fully qualified name (including the namespace.)
191-
const indexOfDot = schemaName.lastIndexOf('.');
192-
if (indexOfDot > 0) {
193-
return { className: schemaName.substring(indexOfDot + 1), javaPackage: schemaName.substring(0, indexOfDot) };
194-
}
195-
return { className: schemaName, javaPackage: undefined };
196-
}
197-
198191
reset() {
199192
instanceMap.forEach((val) => {
200193
val.superClassMap = null;

lib/scsLib.js

+15
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,21 @@ class ScsLib {
8585
return isProvider ? channel.subscribe() : channel.publish();
8686
}
8787

88+
/**
89+
* Takes a string, splits on the last instance of '.' (dot) if it exists and returns an object of the separated pieces.
90+
*
91+
* @param {String} dotSeparatedName Example: 'com.solace.api.Schema'.
92+
* @returns {Object} { javaPackage, className } Example: { javaPackage: "com.solace.api", className: "Schema" }.
93+
*/
94+
stripPackageName(dotSeparatedName) {
95+
// If there is a dot in the schema name, it's probably an Avro schema with a fully qualified name (including the namespace.)
96+
const indexOfDot = dotSeparatedName.lastIndexOf('.');
97+
if (indexOfDot > 0) {
98+
return { javaPackage: dotSeparatedName.substring(0, indexOfDot), className: dotSeparatedName.substring(indexOfDot + 1) };
99+
}
100+
return { className: dotSeparatedName };
101+
}
102+
88103
initReservedWords() {
89104
// This is the set of Java reserved words, to ensure that we don't generate any by mistake.
90105
ScsLib.javaKeywords = new Set();

0 commit comments

Comments
 (0)