Skip to content

Commit

Permalink
feat: added example to generate all models within the same file (#1054)
Browse files Browse the repository at this point in the history
  • Loading branch information
anaysarkar7 authored Dec 21, 2022
1 parent de5a94b commit 5a8650a
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 10 deletions.
33 changes: 23 additions & 10 deletions docs/advanced.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
# Advanced use-cases for Modelina

This document contains many of the advanced use-cases that you may stumble upon when pushing the limits of Modelina.

<!-- toc is generated with GitHub Actions do not remove toc markers -->

<!-- toc -->

- [Generate each model in the same file](#generate-each-model-in-the-same-file)
- [Generate models to separate files](#generate-models-to-separate-files)
- [Include a custom function in the data model](#include-a-custom-function-in-the-data-model)
- [Use the models for data transfer](#use-the-models-for-data-transfer)
- [Adapting input and outputs](#adapting-input-and-outputs)
- [Add logging to library](#add-logging-to-library)
- [Change the generated indentation type and size](#change-the-generated-indentation-type-and-size)
- [Change the type mapping](#change-the-type-mapping)
- [Changing the constrain rules](#changing-the-constrain-rules)
- [Advanced use-cases for Modelina](#advanced-use-cases-for-modelina)
- [Generate each model in the same file](#generate-each-model-in-the-same-file)
- [Generate models to separate files](#generate-models-to-separate-files)
- [Include a custom function in the data model](#include-a-custom-function-in-the-data-model)
- [Use the models for data transfer](#use-the-models-for-data-transfer)
- [Adapting input and outputs](#adapting-input-and-outputs)
- [Add logging to library](#add-logging-to-library)
- [Change the generated indentation type and size](#change-the-generated-indentation-type-and-size)
- [Change the type mapping](#change-the-type-mapping)
- [Changing the constrain rules](#changing-the-constrain-rules)

<!-- tocstop -->

## Generate each model in the same file
TODO

This example shows us how to generate each model in the same file

Check out this [example out for a live demonstration](../examples/generate-all-models-within-same-file).

## Generate models to separate files

Expand All @@ -33,11 +38,13 @@ The file generators all follow the same pattern regardless of output language, w
Check out this [example out for a live demonstration](../examples/generate-to-files).

## Include a custom function in the data model

Sometimes you want to include custom functionality into the generated models, this can be done through a custom preset using the hook `additionalContent`.

Check out this [example out for a live demonstration](../examples/include-custom-function).

## Use the models for data transfer

One of the primary use-cases for the generated models, is to serialize and deserilize it to for example JSON, XML or binary. Each generator can have multiple ways to achieve this, and even support multiple libraries. This is achieved through presets, you can find them here for each output:

- [C#](./languages/Csharp.md#generate-serializer-and-deserializer-functionality)
Expand All @@ -49,18 +56,21 @@ One of the primary use-cases for the generated models, is to serialize and deser
- [TypeScript](./languages/TypeScript.md#generate-serializer-and-deserializer-functionality)

## Adapting input and outputs

Sometimes you simply cannot make two things work together as you wished, maybe the input does not support it, or Modelina natively doesn't. However, because of the nature with presets, we can make it work anyway.

> With great customization comes a great responsibility. Always make sure to raise your issue before trying workarounds, maybe you are not alone in the problem, and it should be natively supported, so please make your due diligence before venturing into this :pray: And always feel free to reach out on the AsyncAPI slack channel if you want some quicker feedback!
Check out this [example for a demonstration of how to adapt the input and out to a specific use-case](../examples/adapting-input-and-output).

## Add logging to library

When you generate models, by default, nothing is logged to the console or elsewhere.

If you want to integrate a logging implementation specific to your needs, this library allows you to implement a detached logging module.

The library uses 4 different logging levels:

- `debug`: for specific details only relevant to debugging
- `info`: for general information relevant to the user
- `warn`: for warnings a user may need if the output is not as expected
Expand All @@ -69,16 +79,19 @@ The library uses 4 different logging levels:
Check out this [example out for a live demonstration](../examples/custom-logging).

## Change the generated indentation type and size

In some scenarios, depending on how you stitch them together, you might need to change the indentation type or size and both of these cases are fully supported.

Check out this [example out for a live demonstration](../examples/indentation-type-and-size).

## Change the type mapping

Sometimes, the default type mapping simply dont use the types you expected, or fit into your use-case. Thats why the entire mapping from [MetaModels](./internal-model.md#the-meta-model) to constrained types can be altered.

Check out this [example out for a live demonstration](../examples/change-type-mapping).

## Changing the constrain rules

When moving from a [MetaModel](./internal-model.md#the-meta-model) to a [ConstrainedMetaModel](./internal-model.md#the-constrained-meta-model) it means we bind the input to a specific output. That output has specific constraints that the input MUST adhere to, [read more about this here](constraints.md).

There can be multiple reasons why you want to change the default constrain rules, and therefore you can form them to your needs.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
output
17 changes: 17 additions & 0 deletions examples/generate-all-models-within-the-same-file/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generate all models within the same file

A basic example of how to generate all models within the same file.

## How to run this example

Run this example using:

```sh
npm i && npm run start
```

If you are on Windows, use the `start:windows` script instead:

```sh
npm i && npm run start:windows
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Should be able to generate models to files and should log expected output to console 1`] = `
Array [
"
public class Root {
private Email email;
public Email getEmail() { return this.email; }
public void setEmail(Email email) { this.email = email; }
}
public enum Email {
EXAMPLE1_AT_TEST_DOT_COM((String)\\"example1@test.com\\"), EXAMPLE2_AT_TEST_DOT_COM((String)\\"example2@test.com\\");
private String value;
Email(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public static Email fromValue(String value) {
for (Email e : Email.values()) {
if (e.value.equals(value)) {
return e;
}
}
throw new IllegalArgumentException(\\"Unexpected value '\\" + value + \\"'\\");
}
@Override
public String toString() {
return String.valueOf(value);
}
}",
]
`;
24 changes: 24 additions & 0 deletions examples/generate-all-models-within-the-same-file/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const spy = jest.spyOn(global.console, 'log').mockImplementation(() => {
return;
});
import { generate } from './index';
import * as fs from 'fs';
import * as path from 'path';
describe('Should be able to generate models to files', () => {
afterAll(() => {
jest.restoreAllMocks();
});
test('and should log expected output to console', async () => {
const expectedRootDir = __dirname.includes('examples')
? __dirname
: path.resolve(
__dirname,
'./examples/generate-all-models-within-the-same-file/output'
);
const expectedFilePath = path.resolve(expectedRootDir, 'Root.java');
await generate();
expect(spy.mock.calls.length).toBeGreaterThanOrEqual(1);
expect(spy.mock.calls[spy.mock.calls.length - 1]).toMatchSnapshot();
expect(fs.existsSync(expectedFilePath));
});
});
35 changes: 35 additions & 0 deletions examples/generate-all-models-within-the-same-file/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { JavaFileGenerator } from '../../src';
import { promises as fsPromises } from 'fs';

const generator = new JavaFileGenerator();
const jsonSchemaDraft7 = {
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
additionalProperties: false,
properties: {
email: {
type: 'string',
enum: ['example1@test.com', 'example2@test.com'],
},
},
};
export async function generate(): Promise<void> {
const outputFile =
'./output';
const models = await generator.generate(jsonSchemaDraft7);
const modelCode = models.map((outputModel) => {
return outputModel.result;
});
const imports = models.map((outputModel) => {
return outputModel.dependencies;
});
const uniqueImports = [...new Set(imports)];
const codeWithImports = `${uniqueImports.join('\n')}
${modelCode.join('\n')}`;

await fsPromises.writeFile(outputFile, codeWithImports);
console.log(codeWithImports);
}
if (require.main === module) {
generate();
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions examples/generate-all-models-within-the-same-file/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"config": {
"example_name": "generate-all-models-within-the-same-file"
},
"scripts": {
"install": "cd ../.. && npm i",
"start": "../../node_modules/.bin/ts-node --cwd ../../ ./examples/generate-all-models-within-the-same-file/index.ts",
"start:windows": "..\\..\\node_modules\\.bin\\ts-node --cwd ..\\..\\ .\\examples\\generate-all-models-within-the-same-file\\index.ts",
"test": "../../node_modules/.bin/jest --config=../../jest.config.js ./examples/generate-all-models-within-the-same-file/index.spec.ts",
"test:windows": "..\\..\\node_modules\\.bin\\jest --config=..\\..\\jest.config.js examples/generate-all-models-within-the-same-file/index.spec.ts"
}
}

0 comments on commit 5a8650a

Please sign in to comment.