* Emit C# data-annotation attributes for a JSON Schema property. * Returns an array of attribute lines (without trailing newlines).
(schema: JSONSchema7, indent: string, csharpType: string)
| 412 | * Returns an array of attribute lines (without trailing newlines). |
| 413 | */ |
| 414 | function emitDataAnnotations(schema: JSONSchema7, indent: string, csharpType: string): string[] { |
| 415 | const attrs: string[] = []; |
| 416 | const format = schema.format; |
| 417 | |
| 418 | // [Url] + [StringSyntax(StringSyntaxAttribute.Uri)] for format: "uri" |
| 419 | if (format === "uri") { |
| 420 | attrs.push(`${indent}[Url]`); |
| 421 | attrs.push(`${indent}[StringSyntax(StringSyntaxAttribute.Uri)]`); |
| 422 | } |
| 423 | |
| 424 | // [StringSyntax(StringSyntaxAttribute.Regex)] and [RegularExpression] for format: "regex" |
| 425 | if (format === "regex") { |
| 426 | attrs.push(`${indent}[StringSyntax(StringSyntaxAttribute.Regex)]`); |
| 427 | if (typeof schema.pattern === "string") { |
| 428 | attrs.push(`${indent}[RegularExpression("${escapeCSharpStringLiteral(schema.pattern)}")]`); |
| 429 | } |
| 430 | } |
| 431 | |
| 432 | // [Base64String] for base64-encoded string properties |
| 433 | if (format === "byte" || (schema as Record<string, unknown>).contentEncoding === "base64") { |
| 434 | attrs.push(`${indent}[Base64String]`); |
| 435 | } |
| 436 | |
| 437 | // [RegularExpression] for pattern constraints on non-regex-format properties |
| 438 | if (format !== "regex" && typeof schema.pattern === "string") { |
| 439 | attrs.push(`${indent}[RegularExpression("${escapeCSharpStringLiteral(schema.pattern)}")]`); |
| 440 | } |
| 441 | |
| 442 | // [MinLength] / [MaxLength] for string constraints |
| 443 | if (typeof schema.minLength === "number" || typeof schema.maxLength === "number") { |
| 444 | attrs.push( |
| 445 | `${indent}[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Safe for generated string properties: JSON Schema minLength/maxLength map to string length validation, not reflection over trimmed Count members")]` |
| 446 | ); |
| 447 | } |
| 448 | if (typeof schema.minLength === "number") { |
| 449 | attrs.push(`${indent}[MinLength(${schema.minLength})]`); |
| 450 | } |
| 451 | if (typeof schema.maxLength === "number") { |
| 452 | attrs.push(`${indent}[MaxLength(${schema.maxLength})]`); |
| 453 | } |
| 454 | |
| 455 | return attrs; |
| 456 | } |
| 457 | |
| 458 | /** |
| 459 | * Returns true when a TimeSpan-typed property needs a [JsonConverter] attribute. |
no test coverage detected
searching dependent graphs…