* Resolve a JSON Schema property to a Go type string. * Emits nested struct/enum definitions into ctx as a side effect.
(
propSchema: JSONSchema7,
parentTypeName: string,
jsonPropName: string,
isRequired: boolean,
ctx: GoCodegenCtx
)
| 837 | * Emits nested struct/enum definitions into ctx as a side effect. |
| 838 | */ |
| 839 | function resolveGoPropertyType( |
| 840 | propSchema: JSONSchema7, |
| 841 | parentTypeName: string, |
| 842 | jsonPropName: string, |
| 843 | isRequired: boolean, |
| 844 | ctx: GoCodegenCtx |
| 845 | ): string { |
| 846 | const nestedName = parentTypeName + toGoFieldName(jsonPropName); |
| 847 | |
| 848 | // Handle $ref — resolve the reference and generate the referenced type |
| 849 | if (propSchema.$ref && typeof propSchema.$ref === "string") { |
| 850 | const typeName = goRefTypeName(propSchema.$ref, ctx.definitions, ctx.packageName); |
| 851 | const resolved = resolveRef(propSchema.$ref, ctx.definitions); |
| 852 | if (resolved) { |
| 853 | if (resolved.enum) { |
| 854 | if ((resolved.enum as unknown[]).every((value) => typeof value === "string")) { |
| 855 | const enumType = getOrCreateGoEnum(typeName, resolved.enum as string[], ctx, resolved.description, getEnumValueDescriptions(resolved), isSchemaDeprecated(resolved), isSchemaExperimental(resolved)); |
| 856 | return isRequired ? enumType : `*${enumType}`; |
| 857 | } |
| 858 | if (resolved.enum.length === 1) { |
| 859 | return resolveGoPropertyType(schemaForConstValue(resolved.enum[0]), parentTypeName, jsonPropName, isRequired, ctx); |
| 860 | } |
| 861 | return "any"; |
| 862 | } |
| 863 | if (isNamedGoObjectSchema(resolved)) { |
| 864 | emitGoStruct(typeName, resolved, ctx); |
| 865 | return isRequired ? typeName : `*${typeName}`; |
| 866 | } |
| 867 | const resolvedUnion = resolved as JSONSchema7; |
| 868 | if (resolvedUnion.anyOf || resolvedUnion.oneOf) { |
| 869 | emitGoRpcDefinition(refTypeName(propSchema.$ref, ctx.definitions), resolved, ctx); |
| 870 | if (goDiscriminatedUnionInfoForType(typeName, ctx)) { |
| 871 | return typeName; |
| 872 | } |
| 873 | return isRequired ? typeName : `*${typeName}`; |
| 874 | } |
| 875 | return resolveGoPropertyType(resolved, parentTypeName, jsonPropName, isRequired, ctx); |
| 876 | } |
| 877 | // Fallback: use the type name directly |
| 878 | return isRequired ? typeName : `*${typeName}`; |
| 879 | } |
| 880 | |
| 881 | // Handle anyOf |
| 882 | if (propSchema.anyOf) { |
| 883 | const nullableInnerSchema = getNullableInner(propSchema); |
| 884 | if (nullableInnerSchema) { |
| 885 | // anyOf [T, null/{not:{}}] → nullable T |
| 886 | const innerType = resolveGoPropertyType(nullableInnerSchema, parentTypeName, jsonPropName, true, ctx); |
| 887 | // Pointer-wrap if not already a pointer, slice, or map |
| 888 | return goTypeWithOptionalPointer(innerType, ctx); |
| 889 | } |
| 890 | const nonNull = (propSchema.anyOf as JSONSchema7[]).filter((s) => s.type !== "null"); |
| 891 | const hasNull = (propSchema.anyOf as JSONSchema7[]).some((s) => s.type === "null"); |
| 892 | |
| 893 | if (nonNull.length === 1) { |
| 894 | // anyOf [T, null] → nullable T |
| 895 | const innerType = resolveGoPropertyType(nonNull[0], parentTypeName, jsonPropName, true, ctx); |
| 896 | if (isRequired && !hasNull) return innerType; |
no test coverage detected
searching dependent graphs…