Skip to content

Commit 40fda61

Browse files
dkattanCopilot
andcommitted
feat: add TsInterfaceName property to GenerateDtosFor attribute
When set, the generator emits [TsInterface(Name = ...)] on the generated DTO class for Reinforced.Typings. This allows controlling the TypeScript interface name from the Facet attribute without requiring a hand-written attribute in the partial class. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent f9a3f4a commit 40fda61

3 files changed

Lines changed: 24 additions & 0 deletions

File tree

src/Facet.Attributes/GenerateDtosAttribute.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,13 @@ public class GenerateDtosAttribute : Attribute
249249
/// in the attribute always override preset defaults.
250250
/// </summary>
251251
public DtoPreset Preset { get; set; } = DtoPreset.None;
252+
253+
/// <summary>
254+
/// When set, emits a <c>[TsInterface(Name = "...")]</c> attribute on the generated
255+
/// DTO class for Reinforced.Typings. This controls the TypeScript interface name
256+
/// without requiring a hand-written attribute in the partial class.
257+
/// </summary>
258+
public string? TsInterfaceName { get; set; }
252259
}
253260

254261
/// <summary>

src/Facet/GenerateDtosTargetModel.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ internal sealed class GenerateDtosTargetModel : IEquatable<GenerateDtosTargetMod
3131
public bool GenerateProjections { get; }
3232
public bool GenerateReadOnlyProperties { get; }
3333
public string? PropertySuffix { get; }
34+
public string? TsInterfaceName { get; }
3435
public string? ConvertEnumsTo { get; }
3536
public ImmutableArray<string> ExcludeProperties { get; }
3637
public ImmutableArray<FacetMember> Members { get; }
@@ -106,6 +107,7 @@ public GenerateDtosTargetModel(
106107
bool generateProjections,
107108
bool generateReadOnlyProperties,
108109
string? propertySuffix,
110+
string? tsInterfaceName,
109111
string? convertEnumsTo,
110112
ImmutableArray<string> excludeProperties,
111113
ImmutableArray<FacetMember> members,
@@ -131,6 +133,7 @@ public GenerateDtosTargetModel(
131133
GenerateProjections = generateProjections;
132134
GenerateReadOnlyProperties = generateReadOnlyProperties;
133135
PropertySuffix = propertySuffix;
136+
TsInterfaceName = tsInterfaceName;
134137
ConvertEnumsTo = convertEnumsTo;
135138
ExcludeProperties = excludeProperties;
136139
Members = members;
@@ -164,6 +167,7 @@ public GenerateDtosTargetModel WithOutputType(OutputType outputType)
164167
GenerateProjections,
165168
GenerateReadOnlyProperties,
166169
PropertySuffix,
170+
TsInterfaceName,
167171
ConvertEnumsTo,
168172
ExcludeProperties,
169173
Members,
@@ -198,6 +202,7 @@ public GenerateDtosTargetModel WithResolvedMembers(ImmutableArray<FacetMember> m
198202
GenerateProjections,
199203
GenerateReadOnlyProperties,
200204
PropertySuffix,
205+
TsInterfaceName,
201206
ConvertEnumsTo,
202207
ExcludeProperties,
203208
members,
@@ -231,6 +236,7 @@ public GenerateDtosTargetModel WithIssue(OutputTypeIssue issue)
231236
GenerateProjections,
232237
GenerateReadOnlyProperties,
233238
PropertySuffix,
239+
TsInterfaceName,
234240
ConvertEnumsTo,
235241
ExcludeProperties,
236242
Members,
@@ -262,6 +268,7 @@ public bool Equals(GenerateDtosTargetModel? other)
262268
&& GenerateProjections == other.GenerateProjections
263269
&& GenerateReadOnlyProperties == other.GenerateReadOnlyProperties
264270
&& PropertySuffix == other.PropertySuffix
271+
&& TsInterfaceName == other.TsInterfaceName
265272
&& ConvertEnumsTo == other.ConvertEnumsTo
266273
&& ExcludeProperties.SequenceEqual(other.ExcludeProperties)
267274
&& Members.SequenceEqual(other.Members)
@@ -295,6 +302,7 @@ public override int GetHashCode()
295302
hash = hash * 31 + GenerateProjections.GetHashCode();
296303
hash = hash * 31 + GenerateReadOnlyProperties.GetHashCode();
297304
hash = hash * 31 + (PropertySuffix?.GetHashCode() ?? 0);
305+
hash = hash * 31 + (TsInterfaceName?.GetHashCode() ?? 0);
298306
hash = hash * 31 + (ConvertEnumsTo?.GetHashCode() ?? 0);
299307
hash = hash * 31 + UseFullName.GetHashCode();
300308
hash = hash * 31 + ExcludeNavigationProperties.GetHashCode();

src/Facet/Generators/FacetGenerators/GenerateDtosGenerator.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ bool NeedsPatchWireSupport(GenerateDtosTargetModel m) =>
400400
model.GenerateProjections,
401401
model.GenerateReadOnlyProperties,
402402
model.PropertySuffix,
403+
model.TsInterfaceName,
403404
model.ConvertEnumsTo,
404405
model.ExcludeProperties,
405406
model.Members,
@@ -433,6 +434,7 @@ bool NeedsPatchWireSupport(GenerateDtosTargetModel m) =>
433434
var generateProjections = GetNamedArg(attribute.NamedArguments, "GenerateProjections", true);
434435
var generateReadOnlyProperties = GetNamedArg(attribute.NamedArguments, "GenerateReadOnlyProperties", false);
435436
var propertySuffix = GetNamedArg<string?>(attribute.NamedArguments, "PropertySuffix", null);
437+
var tsInterfaceName = GetNamedArg<string?>(attribute.NamedArguments, "TsInterfaceName", null);
436438
var useFullName = GetNamedArg(attribute.NamedArguments, "UseFullName", false);
437439
var convertEnumsTo = ExtractConvertEnumsTo(attribute.NamedArguments);
438440
var preset = GetNamedArg(attribute.NamedArguments, "Preset", DtoPreset.None);
@@ -636,6 +638,7 @@ bool NeedsPatchWireSupport(GenerateDtosTargetModel m) =>
636638
generateProjections,
637639
generateReadOnlyProperties,
638640
propertySuffix,
641+
tsInterfaceName,
639642
convertEnumsTo,
640643
excludeProperties.ToImmutableArray(),
641644
members.ToImmutableArray(),
@@ -881,6 +884,12 @@ private static void GenerateDtoTypeDeclaration(StringBuilder sb, GenerateDtosTar
881884
sb.AppendLine($"/// Generated {purpose} DTO contract for {sourceTypeName}.");
882885
sb.AppendLine($"/// </summary>");
883886

887+
// Emit [TsInterface] attribute for Reinforced.Typings when TsInterfaceName is set.
888+
if (!string.IsNullOrEmpty(model.TsInterfaceName) && GetKind(model.OutputType) != OutputType.Interface)
889+
{
890+
sb.AppendLine($"[Reinforced.Typings.Attributes.TsInterface(Name = \"{model.TsInterfaceName}\")]");
891+
}
892+
884893
if (GetKind(model.OutputType) != OutputType.Interface)
885894
{
886895
if (model.ConvertEnumsTo != null)

0 commit comments

Comments
 (0)