diff --git a/.all-contributorsrc b/.all-contributorsrc index d8f00878dd..c361fe7f22 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -400,6 +400,18 @@ "example" ] }, + { + "login": "zaytsevand", + "name": "Andrey Zaytsev", + "avatar_url": "https://avatars.githubusercontent.com/u/5207748?v=4", + "profile": "https://github.com/zaytsevand", + "contributions": [ + "code", + "example", + "doc", + "test" + ] + }, { "login": "codingtenshi", "name": "Tenshi Codes", @@ -439,6 +451,17 @@ "test" ] }, + { + "login": "anaysarkar7", + "name": "Anay Sarkar", + "avatar_url": "https://avatars.githubusercontent.com/u/53341181?v=4", + "profile": "https://linktr.ee/anaysarkar7", + "contributions": [ + "example", + "code", + "test" + ] + }, { "login": "LouisXhaferi", "name": "Louis Xhaferi", diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..06ec17bab4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +.github/ +docs/ diff --git a/.eslintignore b/.eslintignore index d82e24ca22..0701a4ffd0 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,9 @@ node_modules docs lib -output \ No newline at end of file +output +src/generators/template +test/generators/template +examples/integrate-with-react +src/processors/TemplateInputProcessor.ts +test/processors/TemplateInputProcessor.spec.ts \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index 681325a8cc..5efde8c889 100644 --- a/.eslintrc +++ b/.eslintrc @@ -4,14 +4,16 @@ "@typescript-eslint", "sonarjs", "security", - "github" + "github", + "prettier" ], "extends": [ "eslint:recommended", "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended", "plugin:sonarjs/recommended", - "plugin:security/recommended" + "plugin:security/recommended", + "prettier" ], "rules": { "strict": 0, @@ -78,10 +80,6 @@ ], "no-spaced-func": 2, "semi-spacing": 2, - "quotes": [ - 2, - "single" - ], "key-spacing": [ 2, { @@ -89,19 +87,8 @@ "afterColon": true } ], - "indent": [ - 2, - 2 - ], "no-lonely-if": 2, "no-floating-decimal": 2, - "brace-style": [ - 2, - "1tbs", - { - "allowSingleLine": true - } - ], "comma-style": [ 2, "last" @@ -183,7 +170,9 @@ "prefer-const": 2, "prefer-spread": 2, "prefer-template": 2, - "@typescript-eslint/no-unused-vars": 2 + "@typescript-eslint/no-unused-vars": 2, + "prettier/prettier": 2, + "sonarjs/no-identical-functions": "off" }, "overrides": [ { diff --git a/.github/workflows/if-nodejs-release.yml b/.github/workflows/if-nodejs-release.yml index 73bffb04ad..15eb3ac743 100644 --- a/.github/workflows/if-nodejs-release.yml +++ b/.github/workflows/if-nodejs-release.yml @@ -10,6 +10,7 @@ on: - master # below lines are not enough to have release supported for these branches # make sure configuration of `semantic-release` package mentions these branches + - next - next-spec - next-major - next-major-spec diff --git a/.gitignore b/.gitignore index d6c16e1b48..3cc80de7e1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ node_modules .vscode coverage lib -*.DS_Store \ No newline at end of file +*.DS_Store +.idea +output diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000000..fc98bd3760 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "semi": true, + "trailingComma": "none", + "singleQuote": true, + "printWidth": 80 +} \ No newline at end of file diff --git a/API.md b/API.md index 16026a4649..4dbac13865 100644 --- a/API.md +++ b/API.md @@ -15,9 +15,6 @@ https://www.asyncapi.com/docs/specifications/v2.2.0#schemaObject https://www.asyncapi.com/docs/specifications/v2.3.0#schemaObject
-This class is the wrapper for simplified models and the rest of the context needed for further generate typed models.
-Common internal representation for a model.
JSON Draft7Schema Draft 7 model
Since each input processor can create multiple meta models this is a wrapper to a MetaModel to make that possible.
+OpenAPI 3.0 -> 3.0.4 schema model
Based on Draft 6, but with restricted keywords and definitions @@ -77,34 +77,63 @@ Modifications
Class for processing Swagger inputs
Class for processing X input
+Logger class for the model generation library
This class acts as a forefront for any external loggers which is why it also implements the interface itself.
Default property names for different aspects of the common model
+Converts a CommonModel into multiple models wrapped in a union model.
+Because a CommonModel might contain multiple models, it's name for each of those models would be the same, instead we slightly change the model name. +Each model has it's type as a name prepended to the union name.
+If the CommonModel has multiple types
A CommonNamingConvention implementation shared between generators for different languages.
+Determine whether we have a dictionary or an object. because in some cases inputs might be: +{ "type": "object", "additionalProperties": { "$ref": "#" } } which is to be interpreted as a dictionary not an object model.
Recursively find the proper property name.
-This function ensures that the property name is unique for the model
+Return the original input based on additionalProperties and patternProperties.
+Function creating the right meta model based on additionalProperties and patternProperties.
+Because a lot of the other constrain functions (such as NO_NUMBER_START_CHAR, NO_EMPTY_VALUE, etc) they might manipulate the property names by append, prepend, or manipulate it any other way.
+We then need to make sure that they don't clash with any existing properties, this is what this function handles.
+If so, prepend reserved_
to the property name and recheck.
string
Because a lot of the other constrain functions (such as NO_NUMBER_START_CHAR, NO_EMPTY_VALUE, etc) they might manipulate the enum keys by append, prepend, or manipulate it any other way.
+We then need to make sure that they don't clash with any existing enum keys, this is what this function handles.
+If so, prepend reserved_
to the enum key and recheck.
Function to make it easier to render JS/TS dependencies based on module system
+Function to make an array of ConstrainedMetaModels only contain unique values (ignores different in memory instances)
+Convert a string into utf-8 encoding and return the byte size.
Returns true if and only if a given preset is already included in a list of presets Check is done using referential equality
Try split the model
+Overwrite the nested models with references where required.
+Interpreter function for additionalItems keyword.
Interpreter function for allOf keyword.
It either merges allOf schemas into existing model or if allowed, create inheritance.
Interpreter function for anyOf keyword.
+It puts the schema reference into the items field.
+Interpreter function for const keyword for draft version > 4
Interpreter function for not keyword.
Interpreter function for oneOf keyword.
+It puts the schema reference into the items field.
+Interpreter function for oneOf keyword combined with the allOf keyword.
+It merges the allOf schemas into all of the oneOf schemas. Shared properties are merged. The oneOf schemas are then added as union to the model.
+Interpreter function for oneOf keyword combined with properties.
+It merges the properties of the schema into the oneOf schemas. Shared properties are merged. The oneOf schemas are then added as union to the model.
+Interpreter function for patternProperties keyword.
Interpreter function for interpreting properties keyword.
Post process the interpreted model. By applying the following:
-This function splits up a model if needed and add the new model to the list of models.
-Split up all models which should and use ref instead.
-Check if CommonModel is an enum
Find the name for simplified version of schema
Return true or false based on whether the input object is a regular object or a class
+Taken from: https://stackoverflow.com/a/43197340/6803886
+Merge a non optional value with custom optional values to form a full value that has all properties sat.
+AbstractGenerator
](#AbstractGenerator)
-### abstractGenerator.generateCompleteModels(input, options)
+### abstractGenerator.generateCompleteModels()
Generates the full output of a model, instead of a scattered model.
OutputModels result is no longer the model itself, but including package, package dependencies and model dependencies.
**Kind**: instance method of [AbstractGenerator
](#AbstractGenerator)
-
-| Param | Description |
-| --- | --- |
-| input | |
-| options | to use for rendering full output |
-
-### abstractGenerator.generate(input)
+### abstractGenerator.generate()
Generates a scattered model where dependencies and rendered results are separated.
**Kind**: instance method of [AbstractGenerator
](#AbstractGenerator)
-
-| Param |
-| --- |
-| input |
-
### abstractGenerator.processInput(input)
-Process any of the input formats to the appropriate CommonInputModel type.
+Process any of the input formats to the appropriate InputMetaModel type and split out the meta models
+based on the requirements of the generators
**Kind**: instance method of [AbstractGenerator
](#AbstractGenerator)
@@ -213,23 +251,18 @@ Process any of the input formats to the appropriate CommonInputModel type.
| --- |
| input |
+
+
+### abstractGenerator.getPresets()
+Get all presets (default and custom ones from options) for a given preset type (class, enum, etc).
+
+**Kind**: instance method of [AbstractGenerator
](#AbstractGenerator)
## AbstractRenderer
Abstract renderer with common helper methods
**Kind**: global class
-
-
-### abstractRenderer.addDependency(dependency)
-Adds a dependency while ensuring that only one dependency is preset at a time.
-
-**Kind**: instance method of [AbstractRenderer
](#AbstractRenderer)
-
-| Param | Description |
-| --- | --- |
-| dependency | complete dependency string so it can be rendered as is. |
-
## AsyncapiV2Schema
@@ -254,12 +287,6 @@ Takes a deep copy of the input object and converts it to an instance of Asyncapi
| --- |
| object |
-
-
-## CommonInputModel
-This class is the wrapper for simplified models and the rest of the context needed for further generate typed models.
-
-**Kind**: global class
## CommonModel
@@ -276,21 +303,21 @@ Common internal representation for a model.
* [.isRequired(propertyName)](#CommonModel+isRequired) ⇒ boolean
* [.addItem(itemModel, originalInput)](#CommonModel+addItem)
* [.addItemTuple(tupleModel, originalInput, index)](#CommonModel+addItemTuple)
+ * [.addItemUnion(unionModel)](#CommonModel+addItemUnion)
* [.addEnum(enumValue)](#CommonModel+addEnum)
* [.removeEnum(enumValue)](#CommonModel+removeEnum)
* [.addProperty(propertyName, propertyModel, originalInput)](#CommonModel+addProperty)
* [.addAdditionalProperty(additionalPropertiesModel, originalInput)](#CommonModel+addAdditionalProperty)
- * [.addAdditionalItems(additionalItemsModel, originalInput)](#CommonModel+addAdditionalItems)
* [.addPatternProperty(pattern, patternModel, originalInput)](#CommonModel+addPatternProperty)
+ * [.addAdditionalItems(additionalItemsModel, originalInput)](#CommonModel+addAdditionalItems)
* [.addExtendedModel(extendedModel)](#CommonModel+addExtendedModel)
- * [.getNearestDependencies()](#CommonModel+getNearestDependencies)
* _static_
* [.toCommonModel(object)](#CommonModel.toCommonModel) ⇒
* [.mergeProperties(mergeTo, mergeFrom, originalInput, alreadyIteratedModels)](#CommonModel.mergeProperties)
* [.mergeAdditionalProperties(mergeTo, mergeFrom, originalInput, alreadyIteratedModels)](#CommonModel.mergeAdditionalProperties)
* [.mergeAdditionalItems(mergeTo, mergeFrom, originalInput, alreadyIteratedModels)](#CommonModel.mergeAdditionalItems)
- * [.mergePatternProperties(mergeTo, mergeFrom, originalInput, alreadyIteratedModels)](#CommonModel.mergePatternProperties)
* [.mergeItems(mergeTo, mergeFrom, originalInput, alreadyIteratedModels)](#CommonModel.mergeItems)
+ * [.mergePatternProperties(mergeTo, mergeFrom, originalInput, alreadyIteratedModels)](#CommonModel.mergePatternProperties)
* [.mergeTypes(mergeTo, mergeFrom)](#CommonModel.mergeTypes)
* [.mergeCommonModels(mergeTo, mergeFrom, originalInput, alreadyIteratedModels)](#CommonModel.mergeCommonModels)
@@ -380,6 +407,17 @@ If a item already exist it will be merged.
| originalInput | corresponding input that got interpreted to this model |
| index | |
+
+
+### commonModel.addItemUnion(unionModel)
+Adds a union model to the model.
+
+**Kind**: instance method of [CommonModel
](#CommonModel)
+
+| Param |
+| --- |
+| unionModel |
+
### commonModel.addEnum(enumValue)
@@ -431,31 +469,31 @@ If another model already exist the two are merged.
| additionalPropertiesModel | |
| originalInput | corresponding input that got interpreted to this model corresponding input that got interpreted to this model |
-
+
-### commonModel.addAdditionalItems(additionalItemsModel, originalInput)
-Adds additionalItems to the model.
-If another model already exist the two are merged.
+### commonModel.addPatternProperty(pattern, patternModel, originalInput)
+Adds a patternProperty to the model.
+If the pattern already exist the two models are merged.
**Kind**: instance method of [CommonModel
](#CommonModel)
| Param | Description |
| --- | --- |
-| additionalItemsModel | |
+| pattern | |
+| patternModel | |
| originalInput | corresponding input that got interpreted to this model |
-
+
-### commonModel.addPatternProperty(pattern, patternModel, originalInput)
-Adds a patternProperty to the model.
-If the pattern already exist the two models are merged.
+### commonModel.addAdditionalItems(additionalItemsModel, originalInput)
+Adds additionalItems to the model.
+If another model already exist the two are merged.
**Kind**: instance method of [CommonModel
](#CommonModel)
| Param | Description |
| --- | --- |
-| pattern | |
-| patternModel | |
+| additionalItemsModel | |
| originalInput | corresponding input that got interpreted to this model |
@@ -471,12 +509,6 @@ It is only allowed to extend if the other model have $id and is not already bein
| --- |
| extendedModel |
-
-
-### commonModel.getNearestDependencies()
-Returns an array of unique `$id`s from all the CommonModel's this model depends on.
-
-**Kind**: instance method of [CommonModel
](#CommonModel)
### CommonModel.toCommonModel(object) ⇒
@@ -531,10 +563,10 @@ Merge two common model additionalItems together
| originalInput | corresponding input that got interpreted to this model |
| alreadyIteratedModels | |
-
+
-### CommonModel.mergePatternProperties(mergeTo, mergeFrom, originalInput, alreadyIteratedModels)
-Merge two common model pattern properties together
+### CommonModel.mergeItems(mergeTo, mergeFrom, originalInput, alreadyIteratedModels)
+Merge items together, prefer tuples over simple array since it is more strict.
**Kind**: static method of [CommonModel
](#CommonModel)
@@ -545,10 +577,10 @@ Merge two common model pattern properties together
| originalInput | corresponding input that got interpreted to this model |
| alreadyIteratedModels | |
-
+
-### CommonModel.mergeItems(mergeTo, mergeFrom, originalInput, alreadyIteratedModels)
-Merge items together, prefer tuples over simple array since it is more strict.
+### CommonModel.mergePatternProperties(mergeTo, mergeFrom, originalInput, alreadyIteratedModels)
+Merge two common model pattern properties together
**Kind**: static method of [CommonModel
](#CommonModel)
@@ -636,6 +668,12 @@ Takes a deep copy of the input object and converts it to an instance of Draft7Sc
| --- |
| object |
+
+
+## InputMetaModel
+Since each input processor can create multiple meta models this is a wrapper to a MetaModel to make that possible.
+
+**Kind**: global class
## OpenapiV3Schema
@@ -715,8 +753,8 @@ Class for processing AsyncAPI inputs
* [.shouldProcess(input)](#AsyncAPIInputProcessor+shouldProcess)
* [.tryGetVersionOfDocument(input)](#AsyncAPIInputProcessor+tryGetVersionOfDocument)
* _static_
- * [.convertToInternalSchema(schema)](#AsyncAPIInputProcessor.convertToInternalSchema)
* [.isFromParser(input)](#AsyncAPIInputProcessor.isFromParser)
+ * [.isFromNewParser(input)](#AsyncAPIInputProcessor.isFromNewParser)
@@ -751,23 +789,21 @@ Try to find the AsyncAPI version from the input. If it cannot undefined are retu
| --- |
| input |
-
-
-### AsyncAPIInputProcessor.convertToInternalSchema(schema)
-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.
+### AsyncAPIInputProcessor.isFromParser(input)
+Figure out if input is from the AsyncAPI parser.
**Kind**: static method of [AsyncAPIInputProcessor
](#AsyncAPIInputProcessor)
-| Param | Description |
-| --- | --- |
-| schema | to reflect name for |
+| Param |
+| --- |
+| input |
-
+
-### AsyncAPIInputProcessor.isFromParser(input)
-Figure out if input is from the AsyncAPI js parser.
+### AsyncAPIInputProcessor.isFromNewParser(input)
+Figure out if input is from the new AsyncAPI parser.
**Kind**: static method of [AsyncAPIInputProcessor
](#AsyncAPIInputProcessor)
@@ -830,6 +866,7 @@ Class for processing JSON Schema
* [.processDraft7(input)](#JsonSchemaInputProcessor+processDraft7)
* [.processDraft4(input)](#JsonSchemaInputProcessor+processDraft4)
* [.processDraft6(input)](#JsonSchemaInputProcessor+processDraft6)
+ * [.handleRootReference()](#JsonSchemaInputProcessor+handleRootReference)
* _static_
* [.reflectSchemaNames(schema, namesStack, name, isRoot)](#JsonSchemaInputProcessor.reflectSchemaNames)
* [.ensureNamePattern(previousName, ...newParts)](#JsonSchemaInputProcessor.ensureNamePattern)
@@ -890,6 +927,14 @@ Process a draft-6 schema
| --- | --- |
| input | to process as draft-6 |
+
+
+### jsonSchemaInputProcessor.handleRootReference()
+This is a hotfix and really only a partial solution as it does not cover all cases.
+
+But it's the best we can do until we find or build a better library to handle references.
+
+**Kind**: instance method of [JsonSchemaInputProcessor
](#JsonSchemaInputProcessor)
### JsonSchemaInputProcessor.reflectSchemaNames(schema, namesStack, name, isRoot)
@@ -1051,6 +1096,12 @@ Converts a Swagger 2.0 Schema to the internal schema format.
| schema | to convert |
| name | of the schema |
+
+
+## TemplateInputProcessor
+Class for processing X input
+
+**Kind**: global class
## LoggerClass
@@ -1070,32 +1121,102 @@ Sets the logger to use for the model generation library
| --- | --- |
| logger | to add |
-
+
+
+## convertToUnionModel()
+Converts a CommonModel into multiple models wrapped in a union model.
+
+Because a CommonModel might contain multiple models, it's name for each of those models would be the same, instead we slightly change the model name.
+Each model has it's type as a name prepended to the union name.
+
+If the CommonModel has multiple types
+
+**Kind**: global function
+
+
+## isDictionary()
+Determine whether we have a dictionary or an object. because in some cases inputs might be:
+{ "type": "object", "additionalProperties": { "$ref": "#" } } which is to be interpreted as a dictionary not an object model.
+
+**Kind**: global function
+
+
+## getOriginalInputFromAdditionalAndPatterns()
+Return the original input based on additionalProperties and patternProperties.
+
+**Kind**: global function
+
+
+## convertAdditionalAndPatterns()
+Function creating the right meta model based on additionalProperties and patternProperties.
+
+**Kind**: global function
+
+
+## NO\_DUPLICATE\_PROPERTIES(constrainedObjectModel, objectModel, propertyName, namingFormatter)
+Because a lot of the other constrain functions (such as NO_NUMBER_START_CHAR, NO_EMPTY_VALUE, etc) they might manipulate the property names by append, prepend, or manipulate it any other way.
+We then need to make sure that they don't clash with any existing properties, this is what this function handles.
+If so, prepend `reserved_` to the property name and recheck.
+
+**Kind**: global function
+
+| Param | Description |
+| --- | --- |
+| constrainedObjectModel | the current constrained object model, which contains already existing constrained properties |
+| objectModel | the raw object model which is non-constrained to the output language. |
+| propertyName | one of the properties in objectModel which might have been manipulated |
+| namingFormatter | the name formatter which are used to format the property key |
-## DefaultPropertyNames
-Default property names for different aspects of the common model
+
-**Kind**: global variable
-
+## NO\_DUPLICATE\_ENUM\_KEYS(constrainedEnumModel, enumModel, enumKey, namingFormatter, enumKeyToCheck, onNameChange, onNameChangeToCheck) ⇒ string
+Because a lot of the other constrain functions (such as NO_NUMBER_START_CHAR, NO_EMPTY_VALUE, etc) they might manipulate the enum keys by append, prepend, or manipulate it any other way.
+We then need to make sure that they don't clash with any existing enum keys, this is what this function handles.
+If so, prepend `reserved_` to the enum key and recheck.
-## CommonNamingConventionImplementation
-A CommonNamingConvention implementation shared between generators for different languages.
+**Kind**: global function
+**Returns**: string
- the potential new enum key that does not clash with existing enum keys.
-**Kind**: global variable
-
+| Param | Description |
+| --- | --- |
+| constrainedEnumModel | the current constrained enum model, which contains already existing constrained enum keys |
+| enumModel | the raw enum model which is non-constrained to the output language. |
+| enumKey | one of the enum keys in enumModel which might have been manipulated. |
+| namingFormatter | the name formatter which are used to format the enum key. |
+| enumKeyToCheck | the enum key to use for checking if it already exist, defaults to enumKey. |
+| onNameChange | callback to change the name of the enum key that needs to be returned. |
+| onNameChangeToCheck | callback to change the enum key which is being checked as part of the existing models. |
-## getUniquePropertyName(rootModel, propertyName)
-Recursively find the proper property name.
+
-This function ensures that the property name is unique for the model
+## renderJavaScriptDependency(toImport, fromModule, moduleSystem)
+Function to make it easier to render JS/TS dependencies based on module system
**Kind**: global function
| Param |
| --- |
-| rootModel |
-| propertyName |
+| toImport |
+| fromModule |
+| moduleSystem |
+
+
+
+## makeUnique(array)
+Function to make an array of ConstrainedMetaModels only contain unique values (ignores different in memory instances)
+
+**Kind**: global function
+| Param | Description |
+| --- | --- |
+| array | to make unique |
+
+
+
+## lengthInUtf8Bytes()
+Convert a string into utf-8 encoding and return the byte size.
+
+**Kind**: global function
## hasPreset(presets, preset)
@@ -1109,6 +1230,34 @@ Check is done using referential equality
| presets | the list to check |
| preset | the preset to check for |
+
+
+## trySplitModel(model, options, models) ⇒
+Try split the model
+
+**Kind**: global function
+**Returns**: whether the new or old MetaModel to use.
+
+| Param |
+| --- |
+| model |
+| options |
+| models |
+
+
+
+## split(model, options, models) ⇒
+Overwrite the nested models with references where required.
+
+**Kind**: global function
+**Returns**: an array of all the split models
+
+| Param |
+| --- |
+| model |
+| options |
+| models |
+
## interpretAdditionalItems(schema, model, interpreter, interpreterOptions)
@@ -1153,6 +1302,22 @@ It either merges allOf schemas into existing model or if allowed, create inherit
| interpreter | |
| interpreterOptions | to control the interpret process |
+
+
+## interpretAnyOf(schema, model, interpreter, interpreterOptions)
+Interpreter function for anyOf keyword.
+
+It puts the schema reference into the items field.
+
+**Kind**: global function
+
+| Param | Description |
+| --- | --- |
+| schema | |
+| model | |
+| interpreter | |
+| interpreterOptions | to control the interpret process |
+
## interpretConst(schema, model)
@@ -1232,10 +1397,12 @@ Interpreter function for not keyword.
| interpreter | |
| interpreterOptions | to control the interpret process |
-
+
-## interpretPatternProperties(schema, model, interpreter, interpreterOptions)
-Interpreter function for patternProperties keyword.
+## interpretOneOf(schema, model, interpreter, interpreterOptions)
+Interpreter function for oneOf keyword.
+
+It puts the schema reference into the items field.
**Kind**: global function
@@ -1246,10 +1413,12 @@ Interpreter function for patternProperties keyword.
| interpreter | |
| interpreterOptions | to control the interpret process |
-
+
-## interpretProperties(schema, model, interpreter, interpreterOptions)
-Interpreter function for interpreting properties keyword.
+## interpretOneOfWithAllOf(schema, model, interpreter, interpreterOptions)
+Interpreter function for oneOf keyword combined with the allOf keyword.
+
+It merges the allOf schemas into all of the oneOf schemas. Shared properties are merged. The oneOf schemas are then added as union to the model.
**Kind**: global function
@@ -1260,41 +1429,49 @@ Interpreter function for interpreting properties keyword.
| interpreter | |
| interpreterOptions | to control the interpret process |
-
+
-## postInterpretModel(model)
-Post process the interpreted model. By applying the following:
-- Ensure models are split as required
+## interpretOneOfWithProperties(schema, model, interpreter, interpreterOptions)
+Interpreter function for oneOf keyword combined with properties.
+
+It merges the properties of the schema into the oneOf schemas. Shared properties are merged. The oneOf schemas are then added as union to the model.
**Kind**: global function
-| Param |
-| --- |
-| model |
+| Param | Description |
+| --- | --- |
+| schema | |
+| model | |
+| interpreter | |
+| interpreterOptions | to control the interpret process |
-
+
-## trySplitModels(model, iteratedModels)
-This function splits up a model if needed and add the new model to the list of models.
+## interpretPatternProperties(schema, model, interpreter, interpreterOptions)
+Interpreter function for patternProperties keyword.
**Kind**: global function
| Param | Description |
| --- | --- |
-| model | check if it should be split up |
-| iteratedModels | which have already been split up |
+| schema | |
+| model | |
+| interpreter | |
+| interpreterOptions | to control the interpret process |
-
+
-## ensureModelsAreSplit(model, iteratedModels)
-Split up all models which should and use ref instead.
+## interpretProperties(schema, model, interpreter, interpreterOptions)
+Interpreter function for interpreting properties keyword.
**Kind**: global function
| Param | Description |
| --- | --- |
-| model | to ensure are split |
-| iteratedModels | which are already split |
+| schema | |
+| model | |
+| interpreter | |
+| interpreterOptions | to control the interpret process |
@@ -1340,3 +1517,22 @@ Find the name for simplified version of schema
| --- | --- |
| schema | to find the name |
+
+
+## isClass(obj)
+Return true or false based on whether the input object is a regular object or a class
+
+Taken from: https://stackoverflow.com/a/43197340/6803886
+
+**Kind**: global function
+
+| Param |
+| --- |
+| obj |
+
+
+
+## mergePartialAndDefault()
+Merge a non optional value with custom optional values to form a full value that has all properties sat.
+
+**Kind**: global function
diff --git a/CODEOWNERS b/CODEOWNERS
index e0ce36c98f..ce4a305a3b 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -7,23 +7,23 @@
# The default owners are automatically added as reviewers when you open a pull request unless different owners are specified in the file.
# Core Champions that does a little of everything
-* @magicmatatjahu @jonaslagoni @asyncapi-bot-eve
+* @magicmatatjahu @jonaslagoni @asyncapi-bot-eve
# Documentation champions
/docs
# Input Champions for AsyncAPI input
-*/processors/AsyncAPIInputProcessor*.ts
+*/processors/AsyncAPIInputProcessor*.ts
# Input Champions for TypeScript input
*/processors/TypeScriptInputProcessor*.ts @ron-debajyoti
# Input Champions for OpenAPI input
-*/processors/OpenAPIInputProcessor*.ts
-*/processors/SwaggerInputProcessor*.ts
+*/processors/OpenAPIInputProcessor*.ts
+*/processors/SwaggerInputProcessor*.ts
# Input Champions for JSON Schema input
-*/processors/JsonSchemaInputProcessor*.ts
+*/processors/JsonSchemaInputProcessor*.ts
# Language Champions for TypeScript and it's presets
*/generators/typescript @Samridhi-98
@@ -41,4 +41,10 @@
*/generators/csharp @ron-debajyoti
# Language Champions for Dart and it's presets
-*/generators/dart
\ No newline at end of file
+*/generators/dart
+
+# Language Champions for Rust and its presets
+*/generators/rust @leigh-johnson
+
+# Language Champions for Kotlin and it's presets
+*/generators/kotlin @LouisXhaferi
diff --git a/Dockerfile b/Dockerfile
index d8c30d2aee..10e5b9a616 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,7 +6,7 @@ RUN apt-get update -yq \
# Install nodejs
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - \
- && apt-get install -yq nodejs
+ && apt-get install -yq nodejs
# Install golang
RUN curl -fsSL https://golang.org/dl/go1.16.8.linux-amd64.tar.gz | tar -C /usr/local -xz
@@ -17,9 +17,25 @@ RUN apt install apt-transport-https dirmngr gnupg ca-certificates -yq \
&& apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF \
&& echo "deb https://download.mono-project.com/repo/debian stable-buster main" | tee /etc/apt/sources.list.d/mono-official-stable.list \
&& apt update -yq \
- && apt install mono-devel -yq
+ && apt install mono-devel -yq
-# Setup library
-COPY package-lock.json .
+# Install rust
+RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
+
+# Install Python
+RUN apt-get install -yq python
+
+# Install Kotlin
+RUN apt install -yq wget unzip \
+ && cd /usr/lib \
+ && wget -q https://github.com/JetBrains/kotlin/releases/download/v1.8.0/kotlin-compiler-1.8.0.zip \
+ && unzip -qq kotlin-compiler-*.zip
+
+ENV PATH $PATH:/usr/lib/kotlinc/bin
+
+# Setup library
+RUN apt-get install -yq chromium
+
+COPY package.json package-lock.json ./
RUN npm install
-COPY . .
\ No newline at end of file
+COPY . ./
diff --git a/README.md b/README.md
index 0b7e594649..e67d73fda1 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,4 @@
-[](https://www.asyncapi.com/tools/modelina)
-
-Modelina is the official AsyncAPI SDK to generate data models (i.e. Java/TypeScript classes, Go Structs, etc) from AsyncAPI documents, among other supported inputs.
+[](https://www.asyncapi.com/tools/modelina)
[; +``` + | +
Use the same inputs across a range of different generators | ++ +```typescript +const generator = new TypeScriptGenerator(); +const generator = new CsharpGenerator(); +const generator = new JavaGenerator(); +const generator = new RustGenerator(); +... +const models = await generator.generate(input); +``` + | +
Easily let you interact with the generated models. + +- Want to show the generated models on a website? Sure! +- Want to generate the models into files? Sure! +- Want to combine all the models into one single file? Sure! + +Whatever interaction you need, you can create. | ++ +```typescript +const models = await generator.generate(input); +for (const model in models) { + const generatedCode = generatedModel.result; + const dependencies = generatedModel.dependencies; + const modeltype = generatedModel.model.type; + const modelName = generatedModel.modelName; + ... +} +``` + | +
Easily modify how models are constrained into the output | + ++ +```typescript +const generator = new TypeScriptGenerator({ + constraints: { + modelName: ({modelName}) => { + // Implement your own constraining logic + return modelName; + } + } +}); +``` + | +
Seamlessly layer additional or replacement code on top of each other to customize the models to your use-case | + ++ +```typescript +const generator = new TypeScriptGenerator({ + presets: [ + { + class: { + additionalContent({ content }) { + return `${content} +public myCustomFunction(): string { + return 'A custom function for each class'; +}`; + }, + } + } + ] +}); +const models = await generator.generate(input); +``` + | +
Seamlessly lets you combine multiple layers of additional or replacement code | + ++ +```typescript +const myCustomFunction1 = { + class: { + additionalContent({ content }) { + return `${content} +public myCustomFunction(): string { +return 'A custom function for each class'; +}`; + }, + } +}; +const myCustomFunction2 = {...}; +const generator = new TypeScriptGenerator({ + presets: [ + myCustomFunction1, + myCustomFunction2 + ] +}); +const models = await generator.generate(input); +``` + | +
Supported inputs | -description | +||
---|---|---|---|
AsyncAPI | -We support the following AsyncAPI versions: 2.0.0, 2.1.0, 2.2.0, 2.3.0 and 2.4.0, which generates models for all the defined message payloads. | +We support the following AsyncAPI versions: 2.0.0 -> 2.5.0, which generates models for all the defined message payloads. | |
JSON Schema | @@ -82,8 +194,12 @@ To see the complete feature list for each language, please click the individualWe support the following OpenAPI versions: Swagger 2.0 and OpenAPI 3.0, which generates models for all the defined request and response payloads. | ||
TypeScript file | -We currently support TypeScript type file as input for model generation | +TypeScript | +We currently support TypeScript types as file input for model generation | +
Meta model | +This is the internal representation of a model for Modelina, it is what inputs gets converted to, and what generators are provided to generate code. Instead of relying on an input processor, you can create your own models from scratch and still take advantage on the generators and the features. |
Supported outputs | -Features | +|
---|---|---|
Java | @@ -119,29 +235,69 @@ To see the complete feature list for each language, please click the individualDart | Class and enum generation: json_annotation |
Rust | +Struct/tuple and enum generation: generation of `implement Default`, generate serde macros, custom indentation type and size, etc | +|
Python | +Class and enum generation: custom indentation type and size, etc | +|
Kotlin | +Class and enum generation: use of data classes where appropriate, custom indentation type and size, etc | +
+
+
+
+
+
+
{ +import { DeepPartial, isPresetWithOptions } from '../utils'; +import { AbstractDependencyManager } from './AbstractDependencyManager'; + +export interface CommonGeneratorOptions< + P extends Preset = Preset, + DependencyManager extends AbstractDependencyManager = AbstractDependencyManager +> { indentation?: { type: IndentationTypes; size: number; }; defaultPreset?: P; presets?: Presets
;
- processorOptions?: ProcessorOptions
+ processorOptions?: ProcessorOptions;
+ /**
+ * This dependency manager type serves two functions.
+ * 1. It can be used to provide a factory for generate functions
+ * 2. It can be used to provide a single instance of a dependency manager, to add all dependencies together
+ *
+ * This depends on context and where it's used.
+ */
+ dependencyManager?: (() => DependencyManager) | DependencyManager;
}
export const defaultGeneratorOptions: CommonGeneratorOptions = {
indentation: {
type: IndentationTypes.SPACES,
- size: 2,
+ size: 2
}
};
/**
* Abstract generator which must be implemented by each language
*/
-export abstract class AbstractGenerator