(schema: JSONSchema7, isRequired: boolean, parentClassName: string, propName: string, classes: string[])
| 1510 | } |
| 1511 | |
| 1512 | function resolveRpcType(schema: JSONSchema7, isRequired: boolean, parentClassName: string, propName: string, classes: string[]): string { |
| 1513 | if (isOpaqueJson(schema)) { |
| 1514 | return isRequired ? "JsonElement" : "JsonElement?"; |
| 1515 | } |
| 1516 | // Handle $ref by resolving against schema definitions and generating the referenced class |
| 1517 | if (schema.$ref) { |
| 1518 | const typeName = typeToClassName(refTypeName(schema.$ref, rpcDefinitions)); |
| 1519 | const refSchema = resolveRef(schema.$ref, rpcDefinitions); |
| 1520 | if (!refSchema) { |
| 1521 | return isRequired ? typeName : `${typeName}?`; |
| 1522 | } |
| 1523 | |
| 1524 | if (refSchema.enum && Array.isArray(refSchema.enum)) { |
| 1525 | const enumName = getOrCreateEnum(typeName, "", refSchema.enum as string[], rpcEnumOutput, refSchema.description, getEnumValueDescriptions(refSchema), undefined, isSchemaDeprecated(refSchema), isSchemaExperimental(refSchema) || experimentalRpcTypes.has(typeName)); |
| 1526 | return isRequired ? enumName : `${enumName}?`; |
| 1527 | } |
| 1528 | |
| 1529 | if (refSchema.type === "object" && refSchema.properties) { |
| 1530 | const cls = emitRpcClass(typeName, refSchema, "public", classes); |
| 1531 | if (cls) classes.push(cls); |
| 1532 | return isRequired ? typeName : `${typeName}?`; |
| 1533 | } |
| 1534 | |
| 1535 | return resolveRpcType(refSchema, isRequired, parentClassName, propName, classes); |
| 1536 | } |
| 1537 | // Handle anyOf: [T, null/{not:{}}] → T? (nullable typed property) |
| 1538 | const nullableInner = getNullableInner(schema); |
| 1539 | if (nullableInner) { |
| 1540 | return resolveRpcType(nullableInner, false, parentClassName, propName, classes); |
| 1541 | } |
| 1542 | // Discriminated union: anyOf with multiple variants sharing a const discriminator |
| 1543 | if (schema.anyOf && Array.isArray(schema.anyOf)) { |
| 1544 | const nonNull = schema.anyOf.filter((s) => typeof s === "object" && s !== null && (s as JSONSchema7).type !== "null"); |
| 1545 | if (nonNull.length > 1) { |
| 1546 | const variants = (nonNull as JSONSchema7[]).map((v) => { |
| 1547 | if (v.$ref) { |
| 1548 | const resolved = resolveRef(v.$ref, rpcDefinitions); |
| 1549 | return resolved ?? v; |
| 1550 | } |
| 1551 | return v; |
| 1552 | }); |
| 1553 | const discriminatorInfo = findDiscriminator(variants); |
| 1554 | if (discriminatorInfo) { |
| 1555 | const hasNull = schema.anyOf.length > nonNull.length; |
| 1556 | const baseClassName = (schema.title as string) ?? `${parentClassName}${propName}`; |
| 1557 | if (!emittedRpcClassSchemas.has(baseClassName)) { |
| 1558 | emittedRpcClassSchemas.set(baseClassName, "polymorphic"); |
| 1559 | const nestedMap = new Map<string, string>(); |
| 1560 | const rpcPropertyResolver: PropertyTypeResolver = (propSchema, parentClass, pName, isReq, _kt, nestedCls, enumOut) => { |
| 1561 | const nestedRpcClasses: string[] = []; |
| 1562 | const result = resolveRpcType(propSchema, isReq, parentClass, pName, nestedRpcClasses); |
| 1563 | for (const cls of nestedRpcClasses) { |
| 1564 | nestedCls.set(cls.match(/class (\w+)/)?.[1] ?? cls.slice(0, 40), cls); |
| 1565 | } |
| 1566 | return result; |
| 1567 | }; |
| 1568 | const polymorphicCode = generateDiscriminatedUnionClass(baseClassName, discriminatorInfo, variants, rpcKnownTypes, nestedMap, rpcEnumOutput, schema.description, rpcPropertyResolver, isSchemaExperimental(schema) || experimentalRpcTypes.has(baseClassName)); |
| 1569 | classes.push(polymorphicCode); |
no test coverage detected
searching dependent graphs…