From 1ab45050c36d2fc8b383ea480658c1697de2ef82 Mon Sep 17 00:00:00 2001 From: Raymond Bergen Date: Wed, 3 Jul 2024 11:59:40 +0200 Subject: [PATCH] #1709 Generate C# TimeSpan as a DayJs duration --- .../DateCodeGenerationTests.cs | 24 +++++++++++++++++-- .../DataConversionGenerator.cs | 19 ++++++++++++++- .../Templates/ConvertToClass.liquid | 2 +- .../TypeScriptTypeResolver.cs | 2 +- 4 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/NJsonSchema.CodeGeneration.TypeScript.Tests/DateCodeGenerationTests.cs b/src/NJsonSchema.CodeGeneration.TypeScript.Tests/DateCodeGenerationTests.cs index d62f359c9..ee6bed679 100644 --- a/src/NJsonSchema.CodeGeneration.TypeScript.Tests/DateCodeGenerationTests.cs +++ b/src/NJsonSchema.CodeGeneration.TypeScript.Tests/DateCodeGenerationTests.cs @@ -15,7 +15,7 @@ public class DateCodeGenerationTests 'myTimeSpan': { 'type': 'string', 'format': 'time-span' } } }"; - + [Theory] [InlineData(false)] [InlineData(true)] @@ -148,6 +148,26 @@ public async Task When_date_handling_is_dayjs_then_dayjs_property_is_generated_i Assert.Contains("data[\"myDate\"] = this.myDate ? this.myDate.format('YYYY-MM-DD') : undefined;", code); } + [Fact] + public async Task When_date_handling_is_dayjs_then_duration_property_is_generated_in_class() + { + //// Arrange + var schema = await JsonSchema.FromJsonAsync(Json); + + //// Act + var generator = new TypeScriptGenerator(schema, new TypeScriptGeneratorSettings + { + TypeStyle = TypeScriptTypeStyle.Class, + DateTimeType = TypeScriptDateTimeType.DayJS + }); + var code = generator.GenerateFile("MyClass"); + + //// Assert + Assert.Contains("myTimeSpan: dayjs.Duration", code); + Assert.Contains("this.myTimeSpan = _data[\"myTimeSpan\"] ? dayjs.duration(((val: string) => { const [days, rest] = val.split('.'); const [hours, minutes, seconds, milliseconds] = rest.split(/[:.]/); return dayjs.duration({ days: parseInt(days), hours: parseInt(hours), minutes: parseInt(minutes), seconds: parseInt(seconds), milliseconds: parseInt(milliseconds), }); })(_data[\"myTimeSpan\"].toString())) : undefined;", code); + Assert.Contains("data[\"myTimeSpan\"] = this.myTimeSpan ? this.myTimeSpan.format('D.HH:mm:ss.SSS') : undefined;", code); + } + [Fact] public async Task When_date_handling_is_date_then_date_property_is_generated_in_class() { @@ -168,7 +188,7 @@ public async Task When_date_handling_is_date_then_date_property_is_generated_in_ Assert.Contains("data[\"myDate\"] = this.myDate ? formatDate(this.myDate) : undefined;", code); Assert.Contains("function formatDate(", code); } - + [Fact] public async Task When_date_handling_is_date_then_date_property_is_generated_in_class_with_local_timezone_conversion() { diff --git a/src/NJsonSchema.CodeGeneration.TypeScript/DataConversionGenerator.cs b/src/NJsonSchema.CodeGeneration.TypeScript/DataConversionGenerator.cs index 672bcd731..a008ebd1f 100644 --- a/src/NJsonSchema.CodeGeneration.TypeScript/DataConversionGenerator.cs +++ b/src/NJsonSchema.CodeGeneration.TypeScript/DataConversionGenerator.cs @@ -67,6 +67,7 @@ private static object CreateModel(DataConversionParameters parameters) IsNewableObject = IsNewableObject(parameters.Schema, parameters), IsDate = IsDate(typeSchema.Format, parameters.Settings.DateTimeType), IsDateTime = IsDateTime(typeSchema.Format, parameters.Settings.DateTimeType), + ConstructDateTimeWith = ConstructDateTimeWith(parameters.Value, typeSchema.Format, parameters.Settings.DateTimeType), // Dictionary IsDictionary = typeSchema.IsDictionary, @@ -144,6 +145,11 @@ private static string GetStringToDateTime(DataConversionParameters parameters, J return "DateTime.fromISO"; case TypeScriptDateTimeType.DayJS: + if (typeSchema.Format is JsonFormatStrings.Duration or JsonFormatStrings.TimeSpan) + { + return "dayjs.duration"; + } + return "dayjs"; default: @@ -201,7 +207,7 @@ private static string GetDateTimeToString(DataConversionParameters parameters, J case TypeScriptDateTimeType.DayJS: if (typeSchema.Format is JsonFormatStrings.Duration or JsonFormatStrings.TimeSpan) { - return "format('d.hh:mm:ss.SSS')"; + return "format('D.HH:mm:ss.SSS')"; } return "toISOString()"; @@ -270,6 +276,17 @@ private static bool IsDateTime(string? format, TypeScriptDateTimeType type) return false; } + private static string ConstructDateTimeWith(string? value, string? format, TypeScriptDateTimeType type) + { + if (type == TypeScriptDateTimeType.DayJS && + format is JsonFormatStrings.Duration or JsonFormatStrings.TimeSpan) + { + return $"((val: string) => {{ const [days, rest] = val.split('.'); const [hours, minutes, seconds, milliseconds] = rest.split(/[:.]/); return dayjs.duration({{ days: parseInt(days), hours: parseInt(hours), minutes: parseInt(minutes), seconds: parseInt(seconds), milliseconds: parseInt(milliseconds), }}); }})({value}.toString())"; + } + + return value + ".toString()"; + } + private static bool IsDate(string? format, TypeScriptDateTimeType type) { diff --git a/src/NJsonSchema.CodeGeneration.TypeScript/Templates/ConvertToClass.liquid b/src/NJsonSchema.CodeGeneration.TypeScript/Templates/ConvertToClass.liquid index 21ad6e1f7..2ee780043 100644 --- a/src/NJsonSchema.CodeGeneration.TypeScript/Templates/ConvertToClass.liquid +++ b/src/NJsonSchema.CodeGeneration.TypeScript/Templates/ConvertToClass.liquid @@ -54,7 +54,7 @@ if ({{ Value }}) { {% if IsDate -%} {{ Variable }} = {{ Value }} ? {{ StringToDateOnlyCode }}({{ Value }}.toString()) : {% if HasDefaultValue %}{{ StringToDateOnlyCode }}({{ DefaultValue }}){% else %}{{ NullValue }}{% endif %}; {% elsif IsDateTime -%} -{{ Variable }} = {{ Value }} ? {{ StringToDateCode }}({{ Value }}.toString()) : {% if HasDefaultValue %}{{ StringToDateCode }}({{ DefaultValue }}){% else %}{{ NullValue }}{% endif %}; +{{ Variable }} = {{ Value }} ? {{ StringToDateCode }}({{ ConstructDateTimeWith }}) : {% if HasDefaultValue %}{{ StringToDateCode }}({{ DefaultValue }}){% else %}{{ NullValue }}{% endif %}; {% else -%} {% if HasDefaultValue or NullValue != "undefined" -%} {{ Variable }} = {{ Value }} !== undefined ? {{ Value }} : {% if HasDefaultValue %}{{ DefaultValue }}{% else %}{{ NullValue }}{% endif %}; diff --git a/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptTypeResolver.cs b/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptTypeResolver.cs index b61f02fd2..269e11ff1 100644 --- a/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptTypeResolver.cs +++ b/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptTypeResolver.cs @@ -287,7 +287,7 @@ private string ResolveString(JsonSchema schema, string? typeNameHint) if (schema.Format is JsonFormatStrings.Duration or JsonFormatStrings.TimeSpan) { - return "dayjs.Dayjs"; + return "dayjs.Duration"; } }