From dc6c9ac95f611c6998e0d4a0c929c6cb0c75821c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Jul 2024 00:17:35 +0200 Subject: [PATCH 1/4] chore(deps): bump braces from 3.0.2 to 3.0.3 in /test/runtime/runtime-typescript (#2072) --- test/runtime/runtime-typescript/package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/runtime/runtime-typescript/package-lock.json b/test/runtime/runtime-typescript/package-lock.json index b14d3eab28..645f447060 100644 --- a/test/runtime/runtime-typescript/package-lock.json +++ b/test/runtime/runtime-typescript/package-lock.json @@ -1511,11 +1511,11 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -2030,9 +2030,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, From e7e60330137e987b4e66edf97bf69efe90962353 Mon Sep 17 00:00:00 2001 From: Tom de Vroomen Date: Fri, 19 Jul 2024 22:27:23 +0200 Subject: [PATCH 2/4] feat: allow to use constraints from jakarta namespace for Java and Kotlin models (#2073) --- .../README.md | 17 ++ .../__snapshots__/index.spec.ts.snap | 35 ++++ .../index.spec.ts | 15 ++ .../index.ts | 34 ++++ .../package-lock.json | 10 ++ .../package.json | 10 ++ .../README.md | 17 ++ .../__snapshots__/index.spec.ts.snap | 22 +++ .../index.spec.ts | 15 ++ .../index.ts | 35 ++++ .../package-lock.json | 10 ++ .../package.json | 10 ++ .../java/presets/ConstraintsPreset.ts | 159 +++++++++--------- .../kotlin/presets/ConstraintsPreset.ts | 10 +- .../java/presets/ConstraintsPreset.spec.ts | 77 +++++++-- .../ConstraintsPreset.spec.ts.snap | 66 +++++++- .../kotlin/presets/ConstraintsPreset.spec.ts | 69 ++++++-- .../ConstraintsPreset.spec.ts.snap | 36 +++- 18 files changed, 535 insertions(+), 112 deletions(-) create mode 100644 examples/java-generate-jakarta-constraint-annotation/README.md create mode 100644 examples/java-generate-jakarta-constraint-annotation/__snapshots__/index.spec.ts.snap create mode 100644 examples/java-generate-jakarta-constraint-annotation/index.spec.ts create mode 100644 examples/java-generate-jakarta-constraint-annotation/index.ts create mode 100644 examples/java-generate-jakarta-constraint-annotation/package-lock.json create mode 100644 examples/java-generate-jakarta-constraint-annotation/package.json create mode 100644 examples/kotlin-generate-jakarta-constraint-annotation/README.md create mode 100644 examples/kotlin-generate-jakarta-constraint-annotation/__snapshots__/index.spec.ts.snap create mode 100644 examples/kotlin-generate-jakarta-constraint-annotation/index.spec.ts create mode 100644 examples/kotlin-generate-jakarta-constraint-annotation/index.ts create mode 100644 examples/kotlin-generate-jakarta-constraint-annotation/package-lock.json create mode 100644 examples/kotlin-generate-jakarta-constraint-annotation/package.json diff --git a/examples/java-generate-jakarta-constraint-annotation/README.md b/examples/java-generate-jakarta-constraint-annotation/README.md new file mode 100644 index 0000000000..d956c0c557 --- /dev/null +++ b/examples/java-generate-jakarta-constraint-annotation/README.md @@ -0,0 +1,17 @@ +# Jakarta validation constraints annotations + +A basic example that shows how Java data models having `jakarta.validation.constraints` annotations can be generated. + +## 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 +``` diff --git a/examples/java-generate-jakarta-constraint-annotation/__snapshots__/index.spec.ts.snap b/examples/java-generate-jakarta-constraint-annotation/__snapshots__/index.spec.ts.snap new file mode 100644 index 0000000000..d036c4408d --- /dev/null +++ b/examples/java-generate-jakarta-constraint-annotation/__snapshots__/index.spec.ts.snap @@ -0,0 +1,35 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Should be able to generate models with jakarta.validation.constraints annotations and should log expected output to console 1`] = ` +Array [ + "public class JakartaAnnotation { + @NotNull + @Min(0) + private double minNumberProp; + @NotNull + @Max(99) + private double maxNumberProp; + @Size(min=2, max=3) + private Object[] arrayProp; + @Pattern(regexp=\\"^I_\\") + @Size(min=3) + private String stringProp; + private Map additionalProperties; + + public double getMinNumberProp() { return this.minNumberProp; } + public void setMinNumberProp(double minNumberProp) { this.minNumberProp = minNumberProp; } + + public double getMaxNumberProp() { return this.maxNumberProp; } + public void setMaxNumberProp(double maxNumberProp) { this.maxNumberProp = maxNumberProp; } + + public Object[] getArrayProp() { return this.arrayProp; } + public void setArrayProp(Object[] arrayProp) { this.arrayProp = arrayProp; } + + public String getStringProp() { return this.stringProp; } + public void setStringProp(String stringProp) { this.stringProp = stringProp; } + + public Map getAdditionalProperties() { return this.additionalProperties; } + public void setAdditionalProperties(Map additionalProperties) { this.additionalProperties = additionalProperties; } +}", +] +`; diff --git a/examples/java-generate-jakarta-constraint-annotation/index.spec.ts b/examples/java-generate-jakarta-constraint-annotation/index.spec.ts new file mode 100644 index 0000000000..1e5c1c4d4f --- /dev/null +++ b/examples/java-generate-jakarta-constraint-annotation/index.spec.ts @@ -0,0 +1,15 @@ +const spy = jest.spyOn(global.console, 'log').mockImplementation(() => { + return; +}); +import { generate } from './index'; + +describe('Should be able to generate models with jakarta.validation.constraints annotations', () => { + 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(); + }); +}); diff --git a/examples/java-generate-jakarta-constraint-annotation/index.ts b/examples/java-generate-jakarta-constraint-annotation/index.ts new file mode 100644 index 0000000000..b7325d32cf --- /dev/null +++ b/examples/java-generate-jakarta-constraint-annotation/index.ts @@ -0,0 +1,34 @@ +import { JavaGenerator, JAVA_CONSTRAINTS_PRESET } from '../../src'; + +const generator = new JavaGenerator({ + presets: [ + { + preset: JAVA_CONSTRAINTS_PRESET, + options: { + importFrom: 'jakarta' + } + } + ] +}); +const jsonSchemaDraft7 = { + $schema: 'http://json-schema.org/draft-07/schema#', + $id: 'JakartaAnnotation', + type: 'object', + properties: { + min_number_prop: { type: 'number', minimum: 0 }, + max_number_prop: { type: 'number', exclusiveMaximum: 100 }, + array_prop: { type: 'array', minItems: 2, maxItems: 3 }, + string_prop: { type: 'string', pattern: '^I_', minLength: 3 } + }, + required: ['min_number_prop', 'max_number_prop'] +}; + +export async function generate(): Promise { + const models = await generator.generate(jsonSchemaDraft7); + for (const model of models) { + console.log(model.result); + } +} +if (require.main === module) { + generate(); +} diff --git a/examples/java-generate-jakarta-constraint-annotation/package-lock.json b/examples/java-generate-jakarta-constraint-annotation/package-lock.json new file mode 100644 index 0000000000..1f23d26f33 --- /dev/null +++ b/examples/java-generate-jakarta-constraint-annotation/package-lock.json @@ -0,0 +1,10 @@ +{ + "name": "java-generate-jakarta-constraint-annotation", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "hasInstallScript": true + } + } +} diff --git a/examples/java-generate-jakarta-constraint-annotation/package.json b/examples/java-generate-jakarta-constraint-annotation/package.json new file mode 100644 index 0000000000..4144d6f73c --- /dev/null +++ b/examples/java-generate-jakarta-constraint-annotation/package.json @@ -0,0 +1,10 @@ +{ + "config" : { "example_name" : "java-generate-jakarta-constraint-annotation" }, + "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" + } +} diff --git a/examples/kotlin-generate-jakarta-constraint-annotation/README.md b/examples/kotlin-generate-jakarta-constraint-annotation/README.md new file mode 100644 index 0000000000..7ada06fe52 --- /dev/null +++ b/examples/kotlin-generate-jakarta-constraint-annotation/README.md @@ -0,0 +1,17 @@ +# Jakarta validation constraints annotations + +A basic example that shows how Kotlin data models having `jakarta.validation.constraints` annotations can be generated. + +## 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 +``` diff --git a/examples/kotlin-generate-jakarta-constraint-annotation/__snapshots__/index.spec.ts.snap b/examples/kotlin-generate-jakarta-constraint-annotation/__snapshots__/index.spec.ts.snap new file mode 100644 index 0000000000..d13ab869e8 --- /dev/null +++ b/examples/kotlin-generate-jakarta-constraint-annotation/__snapshots__/index.spec.ts.snap @@ -0,0 +1,22 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Should be able to generate models with jakarta.validation.constraints annotations and should log expected output to console 1`] = ` +Array [ + "data class JakartaAnnotation( + @get:NotNull + @get:Min(0) + val minNumberProp: Double, + @get:NotNull + @get:Max(99) + val maxNumberProp: Double, + @get:Min(101) + val minNumberPropExclusive: Double? = null, + @get:Size(min=2, max=3) + val arrayProp: List? = null, + @get:Pattern(regexp=\\"^I_\\") + @get:Size(min=3) + val stringProp: String? = null, + val additionalProperties: Map? = null, +)", +] +`; diff --git a/examples/kotlin-generate-jakarta-constraint-annotation/index.spec.ts b/examples/kotlin-generate-jakarta-constraint-annotation/index.spec.ts new file mode 100644 index 0000000000..1e5c1c4d4f --- /dev/null +++ b/examples/kotlin-generate-jakarta-constraint-annotation/index.spec.ts @@ -0,0 +1,15 @@ +const spy = jest.spyOn(global.console, 'log').mockImplementation(() => { + return; +}); +import { generate } from './index'; + +describe('Should be able to generate models with jakarta.validation.constraints annotations', () => { + 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(); + }); +}); diff --git a/examples/kotlin-generate-jakarta-constraint-annotation/index.ts b/examples/kotlin-generate-jakarta-constraint-annotation/index.ts new file mode 100644 index 0000000000..70399898cc --- /dev/null +++ b/examples/kotlin-generate-jakarta-constraint-annotation/index.ts @@ -0,0 +1,35 @@ +import { KotlinGenerator, KOTLIN_CONSTRAINTS_PRESET } from '../../src'; + +const generator = new KotlinGenerator({ + presets: [ + { + preset: KOTLIN_CONSTRAINTS_PRESET, + options: { + importFrom: 'jakarta' + } + } + ] +}); +const jsonSchemaDraft7 = { + $schema: 'http://json-schema.org/draft-07/schema#', + $id: 'JakartaAnnotation', + type: 'object', + properties: { + min_number_prop: { type: 'number', minimum: 0 }, + max_number_prop: { type: 'number', exclusiveMaximum: 100 }, + min_number_prop_exclusive: { type: 'number', exclusiveMinimum: 100 }, + array_prop: { type: 'array', minItems: 2, maxItems: 3 }, + string_prop: { type: 'string', pattern: '^I_', minLength: 3 } + }, + required: ['min_number_prop', 'max_number_prop'] +}; + +export async function generate(): Promise { + const models = await generator.generate(jsonSchemaDraft7); + for (const model of models) { + console.log(model.result); + } +} +if (require.main === module) { + generate(); +} diff --git a/examples/kotlin-generate-jakarta-constraint-annotation/package-lock.json b/examples/kotlin-generate-jakarta-constraint-annotation/package-lock.json new file mode 100644 index 0000000000..51d900a025 --- /dev/null +++ b/examples/kotlin-generate-jakarta-constraint-annotation/package-lock.json @@ -0,0 +1,10 @@ +{ + "name": "kotlin-generate-jakarta-constraint-annotation", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "hasInstallScript": true + } + } +} diff --git a/examples/kotlin-generate-jakarta-constraint-annotation/package.json b/examples/kotlin-generate-jakarta-constraint-annotation/package.json new file mode 100644 index 0000000000..de7e66f499 --- /dev/null +++ b/examples/kotlin-generate-jakarta-constraint-annotation/package.json @@ -0,0 +1,10 @@ +{ + "config" : { "example_name" : "kotlin-generate-jakarta-constraint-annotation" }, + "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" + } +} diff --git a/src/generators/java/presets/ConstraintsPreset.ts b/src/generators/java/presets/ConstraintsPreset.ts index 21745a3643..c15a7e200a 100644 --- a/src/generators/java/presets/ConstraintsPreset.ts +++ b/src/generators/java/presets/ConstraintsPreset.ts @@ -6,93 +6,102 @@ import { } from '../../../models'; import { JavaPreset } from '../JavaPreset'; +export interface JavaConstraintsPresetOptions { + useJakarta: false; +} /** * Preset which extends class's getters with annotations from `javax.validation.constraints` package * * @implements {JavaPreset} */ -export const JAVA_CONSTRAINTS_PRESET: JavaPreset = { - class: { - self({ renderer, content }) { - renderer.dependencyManager.addDependency( - 'import javax.validation.constraints.*;' - ); - return content; - }, - // eslint-disable-next-line sonarjs/cognitive-complexity - property({ renderer, property, content, model }) { - if (model.options.isExtended) { - return ''; - } - - const annotations: string[] = []; +export const JAVA_CONSTRAINTS_PRESET: JavaPreset = + { + class: { + self({ renderer, content, options }) { + options = options || { useJakarta: false }; + const importFrom = options.useJakarta ? 'jakarta' : 'javax'; + renderer.dependencyManager.addDependency( + `import ${importFrom}.validation.constraints.*;` + ); + return content; + }, + // eslint-disable-next-line sonarjs/cognitive-complexity + property({ renderer, property, content, model }) { + if (model.options.isExtended) { + return ''; + } - if (property.required) { - annotations.push(renderer.renderAnnotation('NotNull')); - } - const originalInput = property.property.originalInput; + const annotations: string[] = []; - // string - if (property.property instanceof ConstrainedStringModel) { - const pattern = originalInput['pattern']; - if (pattern !== undefined) { - annotations.push( - renderer.renderAnnotation('Pattern', { - regexp: renderer.renderStringLiteral(pattern) - }) - ); - } - const minLength = originalInput['minLength']; - const maxLength = originalInput['maxLength']; - if (minLength !== undefined || maxLength !== undefined) { - annotations.push( - renderer.renderAnnotation('Size', { - min: minLength, - max: maxLength - }) - ); + if (property.required) { + annotations.push(renderer.renderAnnotation('NotNull')); } - } + const originalInput = property.property.originalInput; - // number/integer - if ( - property.property instanceof ConstrainedFloatModel || - property.property instanceof ConstrainedIntegerModel - ) { - const minimum = originalInput['minimum']; - if (minimum !== undefined) { - annotations.push(renderer.renderAnnotation('Min', minimum)); + // string + if (property.property instanceof ConstrainedStringModel) { + const pattern = originalInput['pattern']; + if (pattern !== undefined) { + annotations.push( + renderer.renderAnnotation('Pattern', { + regexp: renderer.renderStringLiteral(pattern) + }) + ); + } + const minLength = originalInput['minLength']; + const maxLength = originalInput['maxLength']; + if (minLength !== undefined || maxLength !== undefined) { + annotations.push( + renderer.renderAnnotation('Size', { + min: minLength, + max: maxLength + }) + ); + } } - const exclusiveMinimum = originalInput['exclusiveMinimum']; - if (exclusiveMinimum !== undefined) { - annotations.push( - renderer.renderAnnotation('Min', exclusiveMinimum + 1) - ); - } - const maximum = originalInput['maximum']; - if (maximum !== undefined) { - annotations.push(renderer.renderAnnotation('Max', maximum)); - } - const exclusiveMaximum = originalInput['exclusiveMaximum']; - if (exclusiveMaximum !== undefined) { - annotations.push( - renderer.renderAnnotation('Max', exclusiveMaximum - 1) - ); + + // number/integer + if ( + property.property instanceof ConstrainedFloatModel || + property.property instanceof ConstrainedIntegerModel + ) { + const minimum = originalInput['minimum']; + if (minimum !== undefined) { + annotations.push(renderer.renderAnnotation('Min', minimum)); + } + const exclusiveMinimum = originalInput['exclusiveMinimum']; + if (exclusiveMinimum !== undefined) { + annotations.push( + renderer.renderAnnotation('Min', exclusiveMinimum + 1) + ); + } + const maximum = originalInput['maximum']; + if (maximum !== undefined) { + annotations.push(renderer.renderAnnotation('Max', maximum)); + } + const exclusiveMaximum = originalInput['exclusiveMaximum']; + if (exclusiveMaximum !== undefined) { + annotations.push( + renderer.renderAnnotation('Max', exclusiveMaximum - 1) + ); + } } - } - // array - if (property.property instanceof ConstrainedArrayModel) { - const minItems = originalInput['minItems']; - const maxItems = originalInput['maxItems']; - if (minItems !== undefined || maxItems !== undefined) { - annotations.push( - renderer.renderAnnotation('Size', { min: minItems, max: maxItems }) - ); + // array + if (property.property instanceof ConstrainedArrayModel) { + const minItems = originalInput['minItems']; + const maxItems = originalInput['maxItems']; + if (minItems !== undefined || maxItems !== undefined) { + annotations.push( + renderer.renderAnnotation('Size', { + min: minItems, + max: maxItems + }) + ); + } } - } - return renderer.renderBlock([...annotations, content]); + return renderer.renderBlock([...annotations, content]); + } } - } -}; + }; diff --git a/src/generators/kotlin/presets/ConstraintsPreset.ts b/src/generators/kotlin/presets/ConstraintsPreset.ts index 3ba7508cc3..447abadae6 100644 --- a/src/generators/kotlin/presets/ConstraintsPreset.ts +++ b/src/generators/kotlin/presets/ConstraintsPreset.ts @@ -8,11 +8,17 @@ import { import { KotlinPreset } from '../KotlinPreset'; import { ClassRenderer } from '../renderers/ClassRenderer'; +export interface KotlinConstraintsPresetOptions { + useJakarta: false; +} + export const KOTLIN_CONSTRAINTS_PRESET: KotlinPreset = { class: { - self({ renderer, content }) { + self({ renderer, content, options }) { + options = options || { useJakarta: false }; + const importFrom = options.useJakarta ? 'jakarta' : 'javax'; renderer.dependencyManager.addDependency( - 'javax.validation.constraints.*' + `${importFrom}.validation.constraints.*` ); return content; }, diff --git a/test/generators/java/presets/ConstraintsPreset.spec.ts b/test/generators/java/presets/ConstraintsPreset.spec.ts index 13a74fa289..76d4c051db 100644 --- a/test/generators/java/presets/ConstraintsPreset.spec.ts +++ b/test/generators/java/presets/ConstraintsPreset.spec.ts @@ -4,27 +4,46 @@ import { } from '../../../../src/generators'; describe('JAVA_CONSTRAINTS_PRESET', () => { - let generator: JavaGenerator; - beforeEach(() => { - generator = new JavaGenerator({ presets: [JAVA_CONSTRAINTS_PRESET] }); + const doc = { + $id: 'Clazz', + type: 'object', + properties: { + min_number_prop: { type: 'number', minimum: 0 }, + max_number_prop: { type: 'number', exclusiveMaximum: 100 }, + array_prop: { type: 'array', minItems: 2, maxItems: 3 }, + string_prop: { + type: 'string', + pattern: '^\\w+("\\.\\w+)*$', + minLength: 3 + } + }, + required: ['min_number_prop', 'max_number_prop'] + }; + + test('should render javax constraints annotations by default', async () => { + const generator = new JavaGenerator({ presets: [JAVA_CONSTRAINTS_PRESET] }); + const expectedDependencies = [ + 'import java.util.Map;', + 'import javax.validation.constraints.*;' + ]; + + const models = await generator.generate(doc); + expect(models).toHaveLength(1); + expect(models[0].result).toMatchSnapshot(); + expect(models[0].dependencies).toEqual(expectedDependencies); }); - test('should render constraints annotations', async () => { - const doc = { - $id: 'Clazz', - type: 'object', - properties: { - min_number_prop: { type: 'number', minimum: 0 }, - max_number_prop: { type: 'number', exclusiveMaximum: 100 }, - array_prop: { type: 'array', minItems: 2, maxItems: 3 }, - string_prop: { - type: 'string', - pattern: '^\\w+("\\.\\w+)*$', - minLength: 3 + test('should render javax constraints annotations when configured', async () => { + const generator = new JavaGenerator({ + presets: [ + { + preset: JAVA_CONSTRAINTS_PRESET, + options: { + useJakarta: false + } } - }, - required: ['min_number_prop', 'max_number_prop'] - }; + ] + }); const expectedDependencies = [ 'import java.util.Map;', 'import javax.validation.constraints.*;' @@ -36,6 +55,28 @@ describe('JAVA_CONSTRAINTS_PRESET', () => { expect(models[0].dependencies).toEqual(expectedDependencies); }); + test('should render jakarta constraints annotations from when configured', async () => { + const generator = new JavaGenerator({ + presets: [ + { + preset: JAVA_CONSTRAINTS_PRESET, + options: { + useJakarta: true + } + } + ] + }); + const expectedDependencies = [ + 'import java.util.Map;', + 'import jakarta.validation.constraints.*;' + ]; + + const models = await generator.generate(doc); + expect(models).toHaveLength(1); + expect(models[0].result).toMatchSnapshot(); + expect(models[0].dependencies).toEqual(expectedDependencies); + }); + test('should not render anything when isExtended is true', async () => { const extend = { $id: 'extend', diff --git a/test/generators/java/presets/__snapshots__/ConstraintsPreset.spec.ts.snap b/test/generators/java/presets/__snapshots__/ConstraintsPreset.spec.ts.snap index 4101fcd470..5fa0e9b3c7 100644 --- a/test/generators/java/presets/__snapshots__/ConstraintsPreset.spec.ts.snap +++ b/test/generators/java/presets/__snapshots__/ConstraintsPreset.spec.ts.snap @@ -22,7 +22,71 @@ Array [ ] `; -exports[`JAVA_CONSTRAINTS_PRESET should render constraints annotations 1`] = ` +exports[`JAVA_CONSTRAINTS_PRESET should render jakarta constraints annotations from when configured 1`] = ` +"public class Clazz { + @NotNull + @Min(0) + private double minNumberProp; + @NotNull + @Max(99) + private double maxNumberProp; + @Size(min=2, max=3) + private Object[] arrayProp; + @Pattern(regexp=\\"^\\\\\\\\w+(\\\\\\"\\\\\\\\.\\\\\\\\w+)*$\\") + @Size(min=3) + private String stringProp; + private Map additionalProperties; + + public double getMinNumberProp() { return this.minNumberProp; } + public void setMinNumberProp(double minNumberProp) { this.minNumberProp = minNumberProp; } + + public double getMaxNumberProp() { return this.maxNumberProp; } + public void setMaxNumberProp(double maxNumberProp) { this.maxNumberProp = maxNumberProp; } + + public Object[] getArrayProp() { return this.arrayProp; } + public void setArrayProp(Object[] arrayProp) { this.arrayProp = arrayProp; } + + public String getStringProp() { return this.stringProp; } + public void setStringProp(String stringProp) { this.stringProp = stringProp; } + + public Map getAdditionalProperties() { return this.additionalProperties; } + public void setAdditionalProperties(Map additionalProperties) { this.additionalProperties = additionalProperties; } +}" +`; + +exports[`JAVA_CONSTRAINTS_PRESET should render javax constraints annotations by default 1`] = ` +"public class Clazz { + @NotNull + @Min(0) + private double minNumberProp; + @NotNull + @Max(99) + private double maxNumberProp; + @Size(min=2, max=3) + private Object[] arrayProp; + @Pattern(regexp=\\"^\\\\\\\\w+(\\\\\\"\\\\\\\\.\\\\\\\\w+)*$\\") + @Size(min=3) + private String stringProp; + private Map additionalProperties; + + public double getMinNumberProp() { return this.minNumberProp; } + public void setMinNumberProp(double minNumberProp) { this.minNumberProp = minNumberProp; } + + public double getMaxNumberProp() { return this.maxNumberProp; } + public void setMaxNumberProp(double maxNumberProp) { this.maxNumberProp = maxNumberProp; } + + public Object[] getArrayProp() { return this.arrayProp; } + public void setArrayProp(Object[] arrayProp) { this.arrayProp = arrayProp; } + + public String getStringProp() { return this.stringProp; } + public void setStringProp(String stringProp) { this.stringProp = stringProp; } + + public Map getAdditionalProperties() { return this.additionalProperties; } + public void setAdditionalProperties(Map additionalProperties) { this.additionalProperties = additionalProperties; } +}" +`; + +exports[`JAVA_CONSTRAINTS_PRESET should render javax constraints annotations when configured 1`] = ` "public class Clazz { @NotNull @Min(0) diff --git a/test/generators/kotlin/presets/ConstraintsPreset.spec.ts b/test/generators/kotlin/presets/ConstraintsPreset.spec.ts index d320810e35..23e84ffcca 100644 --- a/test/generators/kotlin/presets/ConstraintsPreset.spec.ts +++ b/test/generators/kotlin/presets/ConstraintsPreset.spec.ts @@ -1,22 +1,41 @@ import { KotlinGenerator, KOTLIN_CONSTRAINTS_PRESET } from '../../../../src'; describe('KOTLIN_CONSTRAINTS_PRESET', () => { - let generator: KotlinGenerator; - beforeEach(() => { - generator = new KotlinGenerator({ presets: [KOTLIN_CONSTRAINTS_PRESET] }); + const doc = { + $id: 'Clazz', + type: 'object', + properties: { + min_number_prop: { type: 'number', minimum: 0 }, + max_number_prop: { type: 'number', exclusiveMaximum: 100 }, + array_prop: { type: 'array', minItems: 2, maxItems: 3 }, + string_prop: { type: 'string', pattern: '^I_', minLength: 3 } + }, + required: ['min_number_prop', 'max_number_prop'] + }; + + test('should render javax constraints annotations by default', async () => { + const generator = new KotlinGenerator({ + presets: [KOTLIN_CONSTRAINTS_PRESET] + }); + const expectedDependencies = ['import javax.validation.constraints.*']; + + const models = await generator.generate(doc); + expect(models).toHaveLength(1); + expect(models[0].result).toMatchSnapshot(); + expect(models[0].dependencies).toEqual(expectedDependencies); }); - test('should render constraints annotations', async () => { - const doc = { - $id: 'Clazz', - type: 'object', - properties: { - min_number_prop: { type: 'number', minimum: 0 }, - max_number_prop: { type: 'number', exclusiveMaximum: 100 }, - array_prop: { type: 'array', minItems: 2, maxItems: 3 }, - string_prop: { type: 'string', pattern: '^I_', minLength: 3 } - }, - required: ['min_number_prop', 'max_number_prop'] - }; + test('should render javax constraints annotations when configured', async () => { + const generator = new KotlinGenerator({ + presets: [ + { + preset: KOTLIN_CONSTRAINTS_PRESET, + options: { + useJakarta: false + } + } + ] + }); + const expectedDependencies = ['import javax.validation.constraints.*']; const models = await generator.generate(doc); @@ -24,4 +43,24 @@ describe('KOTLIN_CONSTRAINTS_PRESET', () => { expect(models[0].result).toMatchSnapshot(); expect(models[0].dependencies).toEqual(expectedDependencies); }); + + test('should render jakarta constraints annotations when configured', async () => { + const generator = new KotlinGenerator({ + presets: [ + { + preset: KOTLIN_CONSTRAINTS_PRESET, + options: { + useJakarta: true + } + } + ] + }); + + const expectedDependencies = ['import jakarta.validation.constraints.*']; + + const models = await generator.generate(doc); + expect(models).toHaveLength(1); + expect(models[0].result).toMatchSnapshot(); + expect(models[0].dependencies).toEqual(expectedDependencies); + }); }); diff --git a/test/generators/kotlin/presets/__snapshots__/ConstraintsPreset.spec.ts.snap b/test/generators/kotlin/presets/__snapshots__/ConstraintsPreset.spec.ts.snap index e47ccb4e5d..31c72a3c58 100644 --- a/test/generators/kotlin/presets/__snapshots__/ConstraintsPreset.spec.ts.snap +++ b/test/generators/kotlin/presets/__snapshots__/ConstraintsPreset.spec.ts.snap @@ -1,6 +1,40 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`KOTLIN_CONSTRAINTS_PRESET should render constraints annotations 1`] = ` +exports[`KOTLIN_CONSTRAINTS_PRESET should render jakarta constraints annotations when configured 1`] = ` +"data class Clazz( + @get:NotNull + @get:Min(0) + val minNumberProp: Double, + @get:NotNull + @get:Max(99) + val maxNumberProp: Double, + @get:Size(min=2, max=3) + val arrayProp: List? = null, + @get:Pattern(regexp=\\"^I_\\") + @get:Size(min=3) + val stringProp: String? = null, + val additionalProperties: Map? = null, +)" +`; + +exports[`KOTLIN_CONSTRAINTS_PRESET should render javax constraints annotations by default 1`] = ` +"data class Clazz( + @get:NotNull + @get:Min(0) + val minNumberProp: Double, + @get:NotNull + @get:Max(99) + val maxNumberProp: Double, + @get:Size(min=2, max=3) + val arrayProp: List? = null, + @get:Pattern(regexp=\\"^I_\\") + @get:Size(min=3) + val stringProp: String? = null, + val additionalProperties: Map? = null, +)" +`; + +exports[`KOTLIN_CONSTRAINTS_PRESET should render javax constraints annotations when configured 1`] = ` "data class Clazz( @get:NotNull @get:Min(0) From 8781bb45031760972555fdbc109330c32b274ded Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Fri, 19 Jul 2024 22:48:28 +0200 Subject: [PATCH 3/4] chore(release): v3.7.0 (#2075) --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 074c2aef7d..d9bfa31057 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@asyncapi/modelina", - "version": "3.6.0", + "version": "3.7.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@asyncapi/modelina", - "version": "3.6.0", + "version": "3.7.0", "license": "Apache-2.0", "dependencies": { "@apidevtools/json-schema-ref-parser": "^11.1.0", diff --git a/package.json b/package.json index d911bdba7b..0b43d926cb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@asyncapi/modelina", - "version": "3.6.0", + "version": "3.7.0", "description": "Library for generating data models based on inputs such as AsyncAPI, OpenAPI, or JSON Schema documents", "license": "Apache-2.0", "homepage": "https://www.modelina.org", From 774280c7514a0f60bb4683af3cda62be203f6607 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:45:13 +0200 Subject: [PATCH 4/4] docs: add tomdevroomen as a contributor for code, example, and 2 more (#2074) * update README.md * update .all-contributorsrc --------- Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Jonas Lagoni --- .all-contributorsrc | 12 ++++++++++++ README.md | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index e371ac42b8..2f1d4099c6 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1000,6 +1000,18 @@ "code", "test" ] + }, + { + "login": "tomdevroomen", + "name": "Tom de Vroomen", + "avatar_url": "https://avatars.githubusercontent.com/u/4637986?v=4", + "profile": "https://github.com/tomdevroomen", + "contributions": [ + "code", + "example", + "doc", + "test" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index bab2b171cf..e84833ee96 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Discussions](https://img.shields.io/github/discussions/asyncapi/modelina)](https://github.com/asyncapi/modelina/discussions) [![Website](https://img.shields.io/website?label=website&url=https%3A%2F%2Fwww.modelina.org)](https://www.modelina.org) [![Playground](https://img.shields.io/website?label=playground&url=https%3A%2F%2Fwww.modelina.org%2Fplayground)](https://www.modelina.org/playground) -[![All Contributors](https://img.shields.io/badge/all_contributors-92-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-93-orange.svg?style=flat-square)](#contributors-) Your one-stop tool for generating accurate and well-tested models for representing the message payloads. Use it as a tool in your development workflow, or a library in a larger integrations, entirely in your control. @@ -442,6 +442,7 @@ Thanks go out to these wonderful people ([emoji key](https://allcontributors.org Axel Hecht
Axel Hecht

💻 ⚠️ + Tom de Vroomen
Tom de Vroomen

💻 💡 📖 ⚠️