diff --git a/README.md b/README.md index b2a36a4..fa63192 100644 --- a/README.md +++ b/README.md @@ -126,20 +126,20 @@ message Point { ### Per field annotation -| annotation | description | -|----------------------|:-------------------------------------------------------------------------------------------------------------------| -| @Example | json schema examples keyword. Can exists multiple times. | -| @Min or @Minimum | json schema [numeric validator](https://json-schema.org/understanding-json-schema/reference/numeric#range) | -| @Max or @Maximum | json schema [numeric validator](https://json-schema.org/understanding-json-schema/reference/numeric#range) | -| @Pattern | json scheme [string validator](https://json-schema.org/understanding-json-schema/reference/string#regexp) | -| @ExclusiveMinimum | json schema [numeric validator](https://json-schema.org/understanding-json-schema/reference/numeric#range) | -| @ExclusiveMaximum | json schema [numeric validator](https://json-schema.org/understanding-json-schema/reference/numeric#range) | -| @MultipleOf | json schema [numeric validator](https://json-schema.org/understanding-json-schema/reference/numeric#multiples) | -| @MinLength | json scheme [string validator](https://json-schema.org/understanding-json-schema/reference/string#length) | -| @MaxLength | json scheme [string validator](https://json-schema.org/understanding-json-schema/reference/string#length) | -| @MinItems | json scheme [array validator](https://json-schema.org/understanding-json-schema/reference/array#length) | -| @MaxItems | json scheme [array validator](https://json-schema.org/understanding-json-schema/reference/array#length) | -| @Default | json schema [default value](https://opis.io/json-schema/1.x/default-value.html) | +| annotation | description | +|----------------------|:-------------------------------------------------------------------------------------------------------------------------------------| +| @Example | json schema examples keyword. Can exists multiple times. If used with an complex type, an single lines json object hast to be used. | +| @Min or @Minimum | json schema [numeric validator](https://json-schema.org/understanding-json-schema/reference/numeric#range) | +| @Max or @Maximum | json schema [numeric validator](https://json-schema.org/understanding-json-schema/reference/numeric#range) | +| @Pattern | json scheme [string validator](https://json-schema.org/understanding-json-schema/reference/string#regexp) | +| @ExclusiveMinimum | json schema [numeric validator](https://json-schema.org/understanding-json-schema/reference/numeric#range) | +| @ExclusiveMaximum | json schema [numeric validator](https://json-schema.org/understanding-json-schema/reference/numeric#range) | +| @MultipleOf | json schema [numeric validator](https://json-schema.org/understanding-json-schema/reference/numeric#multiples) | +| @MinLength | json scheme [string validator](https://json-schema.org/understanding-json-schema/reference/string#length) | +| @MaxLength | json scheme [string validator](https://json-schema.org/understanding-json-schema/reference/string#length) | +| @MinItems | json scheme [array validator](https://json-schema.org/understanding-json-schema/reference/array#length) | +| @MaxItems | json scheme [array validator](https://json-schema.org/understanding-json-schema/reference/array#length) | +| @Default | json schema [default value](https://opis.io/json-schema/1.x/default-value.html) | ### Per message annotation diff --git a/src/protoj2jsonSchema.ts b/src/protoj2jsonSchema.ts index 7d75c5c..4e4d15c 100644 --- a/src/protoj2jsonSchema.ts +++ b/src/protoj2jsonSchema.ts @@ -9,6 +9,7 @@ import {AsyncAPISchemaDefinition} from '@asyncapi/parser/esm/spec-types/v3'; const ROOT_FILENAME = 'root'; const COMMENT_ROOT_NODE = '@RootNode'; const COMMENT_EXAMPLE = '@Example'; +const COMMENT_DEFAULT = '@Default'; class Proto2JsonSchema { private root = new protobuf.Root(); @@ -296,8 +297,9 @@ class Proto2JsonSchema { comment = comment .replace(new RegExp(`\\s{0,15}${COMMENT_EXAMPLE}\\s{0,15}(.+)`, 'ig'), '') + .replace(new RegExp(`\\s{0,15}${COMMENT_DEFAULT}\\s{0,15}(.+)`, 'ig'), '') .replace(new RegExp(`\\s{0,15}${COMMENT_ROOT_NODE}`, 'ig'), '') - .replace(new RegExp('\\s{0,15}@(Min|Max|Pattern|Minimum|Maximum|ExclusiveMinimum|ExclusiveMaximum|MultipleOf|MaxLength|MinLength|MaxItems|MinItems|Default)\\s{0,15}[\\d.]{1,20}', 'ig'), '') + .replace(new RegExp('\\s{0,15}@(Min|Max|Pattern|Minimum|Maximum|ExclusiveMinimum|ExclusiveMaximum|MultipleOf|MaxLength|MinLength|MaxItems|MinItems)\\s{0,15}[\\d.]{1,20}', 'ig'), '') .trim(); if (comment.length < 1) { @@ -307,19 +309,19 @@ class Proto2JsonSchema { return comment; } - private extractExamples(comment: string | null): string[] | null { + private extractExamples(comment: string | null): (string|ProtoAsJson)[] | null { if (!comment) { return null; } - const examples: string[] = []; + const examples: (string|ProtoAsJson)[] = []; let m: RegExpExecArray | null; const examplePattern = new RegExp(`\\s*${COMMENT_EXAMPLE}\\s(.+)$`, 'i'); for (const line of comment.split('\n')) { if ((m = examplePattern.exec(line)) !== null) { // The result can be accessed through the `m`-variable. - examples.push(m[1].trim()); + examples.push(tryParseToObject(m[1].trim())); } } @@ -376,12 +378,11 @@ class Proto2JsonSchema { if (comment === null || comment?.length < 1) { return; } - - const defaultPattern = /@Default\\s([^\n]+)/i; + const defaultPattern = new RegExp(`\\s*${COMMENT_DEFAULT}\\s(.+)$`, 'i'); let m: RegExpExecArray | null; if ((m = defaultPattern.exec(comment)) !== null) { - obj.default = m[1]; + obj.default = tryParseToObject(m[1]); } } } @@ -395,5 +396,20 @@ function isString(value: any): boolean { return typeof value === 'string' || value instanceof String; } +function tryParseToObject(value: string): string | ProtoAsJson { + if (value.charAt(0) === '{') { + try { + const json = JSON.parse(value); + if (json) { + return json; + } + } catch (_) { + // Ignored error, seams not to be a valid json. Maybe just an example starting with an { but is not a json. + } + } + + return value; +} + type ProtoAsJson = { [k: string]: any }; type ProtoItems = { [k: string]: protobuf.ReflectionObject }; diff --git a/test/documents/realworld.train_run.proto.result.json b/test/documents/realworld.train_run.proto.result.json index e148a82..92eead5 100644 --- a/test/documents/realworld.train_run.proto.result.json +++ b/test/documents/realworld.train_run.proto.result.json @@ -144,6 +144,16 @@ } }, + "default": { + "seconds": 946681200, + "nanos": 0 + }, + "examples": [ + { + "seconds": 1706685920, + "nanos": 0 + } + ], }, "composition": { @@ -958,6 +968,16 @@ } }, + "default": { + "seconds": 946681200, + "nanos": 0 + }, + "examples": [ + { + "seconds": 1706685920, + "nanos": 0 + } + ], }, "composition": { diff --git a/test/documents/realworld.train_run.yaml b/test/documents/realworld.train_run.yaml index 1927621..204a930 100644 --- a/test/documents/realworld.train_run.yaml +++ b/test/documents/realworld.train_run.yaml @@ -47,6 +47,10 @@ components: string zugnummer = 4; string infrastruktur_netz = 5; PeriodMsg object_period = 6; + /* + * @Example { "seconds": 1706685920, "nanos": 0 } + * @Default { "seconds": 946681200, "nanos": 0 } + */ google.protobuf.Duration dr = 7; CompositionMsg composition = 8; }