1- import type { Symbol } from '@hey-api/codegen-core' ;
21import type { SchemaWithType } from '@hey-api/shared' ;
32import { toCase } from '@hey-api/shared' ;
43
54import { $ } from '../../../../py-dsl' ;
5+ import type { EnumResolverContext } from '../../resolvers' ;
66import type { PydanticFinal , PydanticType } from '../../shared/types' ;
77import type { PydanticPlugin } from '../../types' ;
88
@@ -21,13 +21,8 @@ function toEnumMemberName(value: string | number): string {
2121 return toCase ( value , 'SCREAMING_SNAKE_CASE' ) ;
2222}
2323
24- function extractEnumMembers (
25- schema : SchemaWithType < 'enum' > ,
26- plugin : PydanticPlugin [ 'Instance' ] ,
27- ) : {
28- enumMembers : Required < PydanticFinal > [ 'enumMembers' ] ;
29- isNullable : boolean ;
30- } {
24+ function itemsNode ( ctx : EnumResolverContext ) {
25+ const { plugin, schema } = ctx ;
3126 const enumMembers : Required < PydanticFinal > [ 'enumMembers' ] = [ ] ;
3227 let isNullable = false ;
3328
@@ -51,51 +46,67 @@ function extractEnumMembers(
5146 return { enumMembers, isNullable } ;
5247}
5348
54- function toLiteralType (
55- enumMembers : Required < PydanticFinal > [ 'enumMembers' ] ,
56- plugin : PydanticPlugin [ 'Instance' ] ,
57- ) : string | Symbol | ReturnType < typeof $ . subscript > {
49+ function baseNode ( ctx : EnumResolverContext ) : PydanticType {
50+ const { plugin } = ctx ;
51+ const { enumMembers } = ctx . nodes . items ( ctx ) ;
52+
5853 if ( enumMembers . length === 0 ) {
59- return plugin . external ( 'typing.Any' ) ;
54+ return {
55+ type : plugin . external ( 'typing.Any' ) ,
56+ } ;
57+ }
58+
59+ const mode = plugin . config . enums ?? 'enum' ;
60+
61+ if ( mode === 'literal' ) {
62+ if ( enumMembers . length === 0 ) {
63+ return {
64+ type : plugin . external ( 'typing.Any' ) ,
65+ } ;
66+ }
67+
68+ const literal = plugin . external ( 'typing.Literal' ) ;
69+ const values = enumMembers . map ( ( m ) =>
70+ // TODO: replace
71+ typeof m . value === 'string' ? `"<<<<${ m . value } "` : `<<<${ m . value } ` ,
72+ ) ;
73+
74+ return {
75+ type : $ ( literal ) . slice ( ...values ) ,
76+ } ;
6077 }
6178
62- const literal = plugin . external ( 'typing.Literal' ) ;
63- const values = enumMembers . map ( ( m ) =>
64- // TODO: replace
65- typeof m . value === 'string' ? `"<<<<${ m . value } "` : `<<<${ m . value } ` ,
66- ) ;
79+ return { } ;
80+ }
6781
68- return $ ( literal ) . slice ( ...values ) ;
82+ function enumResolver ( ctx : EnumResolverContext ) : PydanticType {
83+ return ctx . nodes . base ( ctx ) ;
6984}
7085
7186export function enumToType ( {
72- mode = 'enum' ,
7387 plugin,
7488 schema,
7589} : {
76- mode ?: 'enum' | 'literal' ;
7790 plugin : PydanticPlugin [ 'Instance' ] ;
7891 schema : SchemaWithType < 'enum' > ;
7992} ) : EnumToTypeResult {
80- const { enumMembers, isNullable } = extractEnumMembers ( schema , plugin ) ;
93+ const ctx : EnumResolverContext = {
94+ $,
95+ nodes : {
96+ base : baseNode ,
97+ items : itemsNode ,
98+ } ,
99+ plugin,
100+ schema,
101+ } ;
81102
82- if ( enumMembers . length === 0 ) {
83- return {
84- enumMembers,
85- isNullable,
86- type : plugin . external ( 'typing.Any' ) ,
87- } ;
88- }
103+ const resolver = plugin . config [ '~resolvers' ] ?. enum ;
104+ const resolved = resolver ?.( ctx ) ?? enumResolver ( ctx ) ;
89105
90- if ( mode === 'literal' ) {
91- return {
92- enumMembers,
93- isNullable,
94- type : toLiteralType ( enumMembers , plugin ) ,
95- } ;
96- }
106+ const { enumMembers, isNullable } = ctx . nodes . items ( ctx ) ;
97107
98108 return {
109+ ...resolved ,
99110 enumMembers,
100111 isNullable,
101112 } ;
0 commit comments