Skip to content

Commit

Permalink
feat: enable raw properties for interface (#1729)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonaslagoni authored Jan 15, 2024
1 parent b356ca6 commit 3713983
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 4 deletions.
9 changes: 8 additions & 1 deletion docs/languages/TypeScript.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ There are special use-cases that each language supports; this document pertains
- [Generate example data function](#generate-example-data-function)
- [Rendering complete models to a specific module system](#rendering-complete-models-to-a-specific-module-system)
- [Rendering comments from description and example fields](#rendering-comments-from-description-and-example-fields)
- [Rendering raw properties for interface](#rendering-raw-properties-for-interface)

<!-- tocstop -->

Expand Down Expand Up @@ -101,4 +102,10 @@ Check out this [example for a live demonstration how to generate the complete Ty
## Rendering comments from description and example fields
You can use the `TS_DESCRIPTION_PRESET` to generate JSDoc style comments from description and example fields in your model.

See [this example](../../examples/typescript-generate-comments) for how this can be used.
See [this example](../../examples/typescript-generate-comments) for how this can be used.

## Rendering raw properties for interface

You can use the `rawPropertyNames: true` and `modelType: 'interface'` together to generate models that use raw properties.

See [this example](../../examples/typescript-generate-raw-properties) for how this can be used.
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ These are all specific examples only relevant to the TypeScript generator:
- [typescript-use-esm](./typescript-use-esm) - A basic example that generate the models to use ESM module system.
- [typescript-use-cjs](./typescript-use-cjs) - A basic example that generate the models to use CJS module system.
- [typescript-generate-jsonbinpack](./typescript-generate-jsonbinpack) - A basic example showing how to generate models that include [jsonbinpack](https://github.com/sourcemeta/jsonbinpack) functionality.
- [typescript-generate-raw-properties](./typescript-generate-raw-properties) - A basic example showing how to generate models that use raw properties for interface.
- [typescript-use-js-reserved-keyword](./typescript-use-js-reserved-keyword) - A basic example showing how you can generate the models that take reserved JS keywords into account for model names, properties or enum keys.


Expand Down
17 changes: 17 additions & 0 deletions examples/typescript-generate-raw-properties/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# TypeScript generate with raw properties

A basic example of how to use Modelina and output a TypeScript models that only use raw properties for interfaces.

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

exports[`Should be able to render raw properties and should log expected output to console 1`] = `
Array [
"interface Root {
'weird name'?: string;
}",
]
`;
15 changes: 15 additions & 0 deletions examples/typescript-generate-raw-properties/index.spec.ts
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 raw properties', () => {
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();
});
});
27 changes: 27 additions & 0 deletions examples/typescript-generate-raw-properties/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { TypeScriptGenerator } from '../../src';

const generator = new TypeScriptGenerator({
rawPropertyNames: true,
modelType: 'interface'
});
const jsonSchemaDraft7 = {
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
additionalProperties: false,
properties: {
'weird name': {
type: 'string',
format: 'email'
}
}
};

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();
}
10 changes: 10 additions & 0 deletions examples/typescript-generate-raw-properties/package-lock.json

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

10 changes: 10 additions & 0 deletions examples/typescript-generate-raw-properties/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"config" : { "example_name" : "typescript-generate-raw-properties" },
"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"
}
}
14 changes: 11 additions & 3 deletions src/generators/typescript/TypeScriptObjectRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,17 @@ export abstract class TypeScriptObjectRenderer extends TypeScriptRenderer<Constr
}

renderProperty(property: ConstrainedObjectPropertyModel): string {
const renderedProperty = `${property.propertyName}${
property.required === false ? '?' : ''
}`;
const requiredProperty = property.required === false ? '?' : '';
let preRenderedProperty;
if (
this.options.rawPropertyNames &&
this.options.modelType === 'interface'
) {
preRenderedProperty = `'${property.unconstrainedPropertyName}'`;
} else {
preRenderedProperty = property.propertyName;
}
const renderedProperty = `${preRenderedProperty}${requiredProperty}`;

if (property.property.options.const?.value) {
return `${renderedProperty}: ${property.property.options.const.value}${
Expand Down

0 comments on commit 3713983

Please sign in to comment.