Skip to content

Commit

Permalink
feat: enable customization of additional property represenation (#1880)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonaslagoni authored Mar 26, 2024
1 parent 0e4cc28 commit d786036
Show file tree
Hide file tree
Showing 11 changed files with 117 additions and 5 deletions.
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ These examples show a specific input and how they can be used:
- [json-schema-draft6-from-object](./json-schema-draft6-from-object) - A basic example where a JSON Schema draft 6 JS object is used to generate models.
- [json-schema-draft4-from-object](./json-schema-draft4-from-object) - A basic example where a JSON Schema draft 4 JS object is used to generate models.
- [json-schema-single-enum-as-const](./json-schema-single-enum-as-const) - An advanced example that shows how to change how `enum` are interpreted when containing a single value.
- [json-schema-additional-properties-representation](./json-schema-additional-properties-representation) - An advanced example that shows how to change the property name for additional properties
- [swagger2.0-from-object](./swagger2.0-from-object) - A basic example where a Swagger 2.0 JS object is used to generate models.
- [meta-model](./meta-model) - A basic example how to provide a meta model for the generator


## General examples
These are examples that can be applied in all scenarios.
- [include-custom-function](./include-custom-function) - A basic example where a custom function is included.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# JSON Schema change property name for additional properties

This example shows how to use the `propertyNameForAdditionalProperties` option on the JSON Schema input processor to change the property name that is used for representing additional properties.

## 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,24 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Should be able to render object with different additional property and should log expected output to console 1`] = `
Array [
"class Root {
private _email?: string;
private _extensions?: Map<string, any>;
constructor(input: {
email?: string,
extensions?: Map<string, any>,
}) {
this._email = input.email;
this._extensions = input.extensions;
}
get email(): string | undefined { return this._email; }
set email(email: string | undefined) { this._email = email; }
get extensions(): Map<string, any> | undefined { return this._extensions; }
set extensions(extensions: Map<string, any> | undefined) { this._extensions = extensions; }
}",
]
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const spy = jest.spyOn(global.console, 'log').mockImplementation(() => {
return;
});
import { generate } from './index';

describe('Should be able to render object with different additional property', () => {
afterAll(() => {
jest.restoreAllMocks();
});
test('and should log expected output to console', async () => {
await generate();
expect(spy.mock.calls.length).toEqual(1);
expect(spy.mock.calls[0]).toMatchSnapshot();
});
});
29 changes: 29 additions & 0 deletions examples/json-schema-additional-properties-representation/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { TypeScriptGenerator } from '../../src';

const generator = new TypeScriptGenerator({
processorOptions: {
jsonSchema: {
propertyNameForAdditionalProperties: 'extensions'
}
}
});
const jsonSchemaDraft7 = {
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
additionalProperties: true,
properties: {
email: {
type: 'string'
}
}
};

export async function generate(): Promise<void> {
const models = await generator.generate(jsonSchemaDraft7);
for (const model of models) {
console.log(model.result);
}
}
if (require.main === module) {
generate();
}

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"config" : { "example_name" : "json-schema-additional-properties-representation" },
"scripts": {
"install": "cd ../.. && npm i",
"start": "../../node_modules/.bin/ts-node --cwd ../../ ./examples/$npm_package_config_example_name/index.ts",
"start:windows": "..\\..\\node_modules\\.bin\\ts-node --cwd ..\\..\\ .\\examples\\%npm_package_config_example_name%\\index.ts",
"test": "../../node_modules/.bin/jest --config=../../jest.config.js ./examples/$npm_package_config_example_name/index.spec.ts",
"test:windows": "..\\..\\node_modules\\.bin\\jest --config=..\\..\\jest.config.js examples/%npm_package_config_example_name%/index.spec.ts"
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Should be able to render TEMPLATE and should log expected output to console 1`] = `
exports[`Should be able to render enum with single value as const and should log expected output to console 1`] = `
Array [
"class Root {
private _email?: 'test' = 'test';
Expand Down
2 changes: 1 addition & 1 deletion examples/json-schema-single-enum-as-const/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const spy = jest.spyOn(global.console, 'log').mockImplementation(() => {
});
import { generate } from './index';

describe('Should be able to render TEMPLATE', () => {
describe('Should be able to render enum with single value as const', () => {
afterAll(() => {
jest.restoreAllMocks();
});
Expand Down
3 changes: 2 additions & 1 deletion src/helpers/CommonModelToMetaModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,8 @@ export function convertToObjectModel(
jsonSchemaModel.additionalProperties !== undefined ||
jsonSchemaModel.patternProperties !== undefined
) {
let propertyName = 'additionalProperties';
let propertyName =
options.propertyNameForAdditionalProperties ?? 'additionalProperties';
while (metaModel.properties[String(propertyName)] !== undefined) {
propertyName = `reserved_${propertyName}`;
}
Expand Down
8 changes: 7 additions & 1 deletion src/processors/JsonSchemaInputProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,20 @@ export interface JsonSchemaProcessorOptions extends InterpreterOptions {
* Use this option to reduce the number of enums being created and use constant values instead.
*/
interpretSingleEnumAsConst?: boolean;

/**
* This option changes which property name that should be used to represent `additionalProperties` in JSON Schema
*/
propertyNameForAdditionalProperties?: string;
}

export const defaultJsonSchemaProcessorOptions: JsonSchemaProcessorOptions = {
allowInheritance: false,
disableCache: false,
ignoreAdditionalItems: false,
ignoreAdditionalProperties: false,
interpretSingleEnumAsConst: false
interpretSingleEnumAsConst: false,
propertyNameForAdditionalProperties: 'additionalProperties'
};

/**
Expand Down

0 comments on commit d786036

Please sign in to comment.