(schema: JSONSchema7, required: boolean, knownTypes: Map<string, string>, propName?: string)
| 335 | } |
| 336 | |
| 337 | function schemaTypeToCSharp(schema: JSONSchema7, required: boolean, knownTypes: Map<string, string>, propName?: string): string { |
| 338 | if (isOpaqueJson(schema)) { |
| 339 | return required ? "JsonElement" : "JsonElement?"; |
| 340 | } |
| 341 | const nullableInner = getNullableInner(schema); |
| 342 | if (nullableInner) { |
| 343 | // Pass required=true to get the base type, then add "?" for nullable |
| 344 | return schemaTypeToCSharp(nullableInner, true, knownTypes, propName) + "?"; |
| 345 | } |
| 346 | if (schema.$ref) { |
| 347 | const refName = schema.$ref.split("/").pop()!; |
| 348 | return knownTypes.get(refName) || refName; |
| 349 | } |
| 350 | // Titled union schemas (anyOf with a title) — use the title if it's a known generated type |
| 351 | if (schema.title && schema.anyOf && knownTypes.has(schema.title)) { |
| 352 | return required ? schema.title : `${schema.title}?`; |
| 353 | } |
| 354 | const type = schema.type; |
| 355 | const format = schema.format; |
| 356 | // Handle type: ["string", "null"] patterns (nullable string) |
| 357 | if (Array.isArray(type)) { |
| 358 | const nonNullTypes = type.filter((t) => t !== "null"); |
| 359 | if (nonNullTypes.length === 1 && nonNullTypes[0] === "string") { |
| 360 | if (format === "uuid") return "Guid?"; |
| 361 | if (format === "date-time") return "DateTimeOffset?"; |
| 362 | return "string?"; |
| 363 | } |
| 364 | if (nonNullTypes.length === 1 && (nonNullTypes[0] === "number" || nonNullTypes[0] === "integer")) { |
| 365 | if (format === "duration" && !isSecondsDurationPropertyName(propName)) { |
| 366 | return "TimeSpan?"; |
| 367 | } |
| 368 | if (nonNullTypes[0] === "integer") { |
| 369 | const integerType = isIntegerSchemaBoundedToInt32(schema) ? "int" : "long"; |
| 370 | return `${integerType}?`; |
| 371 | } |
| 372 | return "double?"; |
| 373 | } |
| 374 | } |
| 375 | if (type === "string") { |
| 376 | if (format === "uuid") return required ? "Guid" : "Guid?"; |
| 377 | if (format === "date-time") return required ? "DateTimeOffset" : "DateTimeOffset?"; |
| 378 | return required ? "string" : "string?"; |
| 379 | } |
| 380 | if (type === "number" || type === "integer") { |
| 381 | if (format === "duration" && !isSecondsDurationPropertyName(propName)) { |
| 382 | return required ? "TimeSpan" : "TimeSpan?"; |
| 383 | } |
| 384 | if (type === "integer") { |
| 385 | const integerType = isIntegerSchemaBoundedToInt32(schema) ? "int" : "long"; |
| 386 | return required ? integerType : `${integerType}?`; |
| 387 | } |
| 388 | return required ? "double" : "double?"; |
| 389 | } |
| 390 | if (type === "boolean") return required ? "bool" : "bool?"; |
| 391 | if (type === "array") { |
| 392 | const items = schema.items as JSONSchema7 | undefined; |
| 393 | if (!items) failUnmappable(`array without items (propName=${propName ?? "?"})`, schema); |
| 394 | const itemType = schemaTypeToCSharp(items, true, knownTypes); |
no test coverage detected
searching dependent graphs…