Skip to content

Commit baf9bd9

Browse files
feat: make it possible to add dependencies to rendering of models (#239)
Co-authored-by: Maciej Urbańczyk <urbanczyk.maciej.95@gmail.com>
1 parent ee5af36 commit baf9bd9

32 files changed

+237
-100
lines changed

docs/presets.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,19 @@ const generator = new TypeScriptGenerator({ presets: [
9696
] });
9797
```
9898

99+
## Adding new dependencies
100+
101+
Each preset hook has the possibility of adding its own dependencies that needs to be rendered for the given model. It can be done through the `addDependency` function from `renderer` property.
102+
103+
```ts
104+
...
105+
self({ renderer, content }) {
106+
renderer.addDependency('import java.util.*;');
107+
return content;
108+
}
109+
...
110+
```
111+
99112
## Overriding the default preset
100113

101114
Each implemented generator for appropriate language must have defined the default preset. However, we can override it by passing it as the `defaultPreset` parameter in the generator options. Check the example for TypeScript generator:

src/generators/AbstractGenerator.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { CommonInputModel, CommonModel, OutputModel, Preset, Presets } from '../
22
import { InputProcessor } from '../processors';
33
import { IndentationTypes } from '../helpers';
44
import { isPresetWithOptions } from '../utils';
5+
import { RenderOutput } from 'models/RenderOutput';
56

67
export interface CommonGeneratorOptions<P extends Preset = Preset> {
78
indentation?: {
@@ -33,7 +34,7 @@ export abstract class AbstractGenerator<Options extends CommonGeneratorOptions =
3334
this.options = this.mergeOptions(defaultOptions, passedOptions);
3435
}
3536

36-
public abstract render(model: CommonModel, inputModel: CommonInputModel): Promise<string>;
37+
public abstract render(model: CommonModel, inputModel: CommonInputModel): Promise<RenderOutput>;
3738

3839
public async process(input: Record<string, unknown>): Promise<CommonInputModel> {
3940
return await InputProcessor.processor.process(input);
@@ -50,8 +51,8 @@ export abstract class AbstractGenerator<Options extends CommonGeneratorOptions =
5051
protected generateModels(inputModel: CommonInputModel): Promise<OutputModel[]> {
5152
const models = inputModel.models;
5253
const renders = Object.entries(models).map(async ([modelName, model]) => {
53-
const result = await this.render(model, inputModel);
54-
return OutputModel.toOutputModel({ result, model, modelName, inputModel });
54+
const renderedOutput = await this.render(model, inputModel);
55+
return OutputModel.toOutputModel({ result: renderedOutput.result, model, modelName, inputModel, dependencies: renderedOutput.dependencies});
5556
});
5657
return Promise.all(renders);
5758
}

src/generators/AbstractRenderer.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,20 @@ export abstract class AbstractRenderer<O extends CommonGeneratorOptions = Common
1111
protected readonly presets: Array<[Preset, unknown]>,
1212
protected readonly model: CommonModel,
1313
protected readonly inputModel: CommonInputModel,
14+
public dependencies: string[] = []
1415
) {}
1516

17+
/**
18+
* Adds a dependency while ensuring that only one dependency is preset at a time.
19+
*
20+
* @param dependency complete dependency string so it can be rendered as is.
21+
*/
22+
addDependency(dependency: string): void {
23+
if (!this.dependencies.includes(dependency)) {
24+
this.dependencies.push(dependency);
25+
}
26+
}
27+
1628
renderLine(line: string): string {
1729
return `${line}\n`;
1830
}
@@ -35,16 +47,15 @@ export abstract class AbstractRenderer<O extends CommonGeneratorOptions = Common
3547
runSelfPreset(): Promise<string> {
3648
return this.runPreset('self');
3749
}
38-
50+
3951
runAdditionalContentPreset(): Promise<string> {
4052
return this.runPreset('additionalContent');
4153
}
42-
43-
async runPreset(
54+
async runPreset<RT = string>(
4455
functionName: string,
4556
params: Record<string, unknown> = {},
46-
): Promise<string> {
47-
let content = '';
57+
): Promise<RT> {
58+
let content;
4859
for (const [preset, options] of this.presets) {
4960
if (typeof preset[String(functionName)] === 'function') {
5061
content = await preset[String(functionName)]({

src/generators/java/JavaGenerator.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@ import {
33
CommonGeneratorOptions,
44
defaultGeneratorOptions,
55
} from '../AbstractGenerator';
6-
import { CommonModel, CommonInputModel } from '../../models';
6+
import { CommonModel, CommonInputModel, RenderOutput } from '../../models';
77
import { ModelKind, TypeHelpers } from '../../helpers';
8-
98
import { JavaPreset, JAVA_DEFAULT_PRESET } from './JavaPreset';
10-
119
import { ClassRenderer } from './renderers/ClassRenderer';
1210
import { EnumRenderer } from './renderers/EnumRenderer';
1311

@@ -25,23 +23,25 @@ export class JavaGenerator extends AbstractGenerator<JavaOptions> {
2523
super('Java', JavaGenerator.defaultOptions, options);
2624
}
2725

28-
render(model: CommonModel, inputModel: CommonInputModel): Promise<string> {
26+
render(model: CommonModel, inputModel: CommonInputModel): Promise<RenderOutput> {
2927
const kind = TypeHelpers.extractKind(model);
3028
if (kind === ModelKind.ENUM) {
3129
return this.renderEnum(model, inputModel);
3230
}
3331
return this.renderClass(model, inputModel);
3432
}
3533

36-
renderClass(model: CommonModel, inputModel: CommonInputModel): Promise<string> {
34+
async renderClass(model: CommonModel, inputModel: CommonInputModel): Promise<RenderOutput> {
3735
const presets = this.getPresets('class');
3836
const renderer = new ClassRenderer(this.options, presets, model, inputModel);
39-
return renderer.runSelfPreset();
37+
const result = await renderer.runSelfPreset();
38+
return RenderOutput.toRenderOutput({result, dependencies: renderer.dependencies});
4039
}
4140

42-
renderEnum(model: CommonModel, inputModel: CommonInputModel): Promise<string> {
41+
async renderEnum(model: CommonModel, inputModel: CommonInputModel): Promise<RenderOutput> {
4342
const presets = this.getPresets('enum');
4443
const renderer = new EnumRenderer(this.options, presets, model, inputModel);
45-
return renderer.runSelfPreset();
44+
const result = await renderer.runSelfPreset();
45+
return RenderOutput.toRenderOutput({result, dependencies: renderer.dependencies});
4646
}
4747
}

src/generators/java/presets/CommonPreset.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ private String toIndentedString(Object o) {
8888
*
8989
* @implements {JavaPreset}
9090
*/
91-
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
9291
export const JAVA_COMMON_PRESET: JavaPreset = {
9392
class: {
9493
additionalContent({ renderer, model, content, options }) {

src/generators/java/presets/ConstraintsPreset.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ import { CommonModel } from '../../../models';
77
*
88
* @implements {JavaPreset}
99
*/
10-
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
1110
export const JAVA_CONSTRAINTS_PRESET: JavaPreset = {
1211
class: {
12+
self({renderer, content}) {
13+
renderer.addDependency('import javax.validation.constraints.*;');
14+
return content;
15+
},
1316
getter({ renderer, model, propertyName, property, content }) {
1417
if (!(property instanceof CommonModel)) {
1518
return content;

src/generators/java/presets/DescriptioPreset.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ function renderDescription({ renderer, content, item }: {
3434
*
3535
* @implements {JavaPreset}
3636
*/
37-
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
3837
export const JAVA_DESCRIPTION_PRESET: JavaPreset = {
3938
class: {
4039
self({ renderer, model, content }) {

src/generators/java/presets/JacksonPreset.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ import { JavaPreset } from '../JavaPreset';
55
*
66
* @implements {JavaPreset}
77
*/
8-
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
98
export const JAVA_JACKSON_PRESET: JavaPreset = {
109
class: {
10+
self({renderer, content}) {
11+
renderer.addDependency('import com.fasterxml.jackson.annotations.*;');
12+
return content;
13+
},
1114
getter({ renderer, propertyName, content }) {
1215
const annotation = renderer.renderAnnotation('JsonProperty', `"${propertyName}"`);
1316
return renderer.renderBlock([annotation, content]);

src/generators/java/renderers/ClassRenderer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export class ClassRenderer extends JavaRenderer {
1616
await this.renderAccessors(),
1717
await this.runAdditionalContentPreset(),
1818
];
19-
19+
2020
const formattedName = this.model.$id && FormatHelpers.toPascalCase(this.model.$id);
2121
return `public class ${formattedName} {
2222
${this.indent(this.renderBlock(content, 2))}

src/generators/java/renderers/EnumRenderer.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { JavaRenderer } from '../JavaRenderer';
2-
3-
import { EnumPreset } from '../../../models';
2+
import { EnumPreset} from '../../../models';
43
import { FormatHelpers } from '../../../helpers';
54

65
/**
@@ -12,7 +11,7 @@ export class EnumRenderer extends JavaRenderer {
1211
async defaultSelf(): Promise<string> {
1312
const content = [
1413
await this.renderItems(),
15-
await this.runAdditionalContentPreset(),
14+
await this.runAdditionalContentPreset()
1615
];
1716

1817
const formattedName = this.model.$id && FormatHelpers.toPascalCase(this.model.$id);
@@ -61,6 +60,7 @@ ${this.indent(this.renderBlock(content, 2))}
6160

6261
export const JAVA_DEFAULT_ENUM_PRESET: EnumPreset<EnumRenderer> = {
6362
self({ renderer }) {
63+
renderer.addDependency('import com.fasterxml.jackson.annotations.*;');
6464
return renderer.defaultSelf();
6565
},
6666
item({ renderer, item }) {

0 commit comments

Comments
 (0)