@@ -127,6 +127,39 @@ const genDef = <Codec extends CodecLike>(
127127 [ codecType as AbstractClass < CodecLike > , generator as CodecGenerator ] as const ;
128128export { genDef as defineCodecGeneratorTuple } ;
129129
130+ type FieldDef = {
131+ name : string ;
132+ cardinality : Cardinality ;
133+ codec : ICodec ;
134+ } ;
135+
136+ const getSortPriority = ( field : FieldDef ) => {
137+ if ( ! ( field . codec instanceof ObjectCodec ) ) {
138+ switch ( field . cardinality ) {
139+ case Cardinality . One :
140+ return 0 ;
141+ case Cardinality . AtLeastOne :
142+ return 1 ;
143+ case Cardinality . AtMostOne :
144+ return 2 ;
145+ case Cardinality . Many :
146+ return 3 ;
147+ }
148+ } else {
149+ switch ( field . cardinality ) {
150+ case Cardinality . One :
151+ return 4 ;
152+ case Cardinality . AtLeastOne :
153+ return 5 ;
154+ case Cardinality . AtMostOne :
155+ return 6 ;
156+ case Cardinality . Many :
157+ return 7 ;
158+ }
159+ }
160+ return 8 ;
161+ } ;
162+
130163export const defaultCodecGenerators : CodecGeneratorMap = new Map ( [
131164 genDef ( NullCodec , ( ) => "null" ) ,
132165 genDef ( EnumCodec , ( codec ) => {
@@ -140,12 +173,27 @@ export const defaultCodecGenerators: CodecGeneratorMap = new Map([
140173 } ) ,
141174 genDef ( ObjectCodec , ( codec , ctx ) => {
142175 const subCodecs = codec . getSubcodecs ( ) ;
143- const fields = codec . getFields ( ) . map ( ( field , i ) => ( {
176+ const originalFields = codec . getFields ( ) ;
177+
178+ const fieldsWithCodecs = originalFields . map ( ( field , i ) => ( {
144179 name : field . name ,
145- codec : subCodecs [ i ] ,
146180 cardinality : util . parseCardinality ( field . cardinality ) ,
181+ codec : subCodecs [ i ] ,
147182 } ) ) ;
148- return generateTsObject ( fields , ctx ) ;
183+
184+ const sortedFieldsWithCodecs = fieldsWithCodecs . sort ( ( a , b ) => {
185+ const aPriority = getSortPriority ( a ) ;
186+ const bPriority = getSortPriority ( b ) ;
187+
188+ if ( aPriority !== bPriority ) {
189+ return aPriority - bPriority ;
190+ }
191+
192+ // Within the same group, sort by name
193+ return a . name . localeCompare ( b . name ) ;
194+ } ) ;
195+
196+ return generateTsObject ( sortedFieldsWithCodecs , ctx ) ;
149197 } ) ,
150198 genDef ( NamedTupleCodec , ( codec , ctx ) => {
151199 const subCodecs = codec . getSubcodecs ( ) ;
@@ -185,18 +233,18 @@ export const defaultCodecGenerators: CodecGeneratorMap = new Map([
185233] ) ;
186234
187235export const generateTsObject = (
188- fields : Parameters < typeof generateTsObjectField > [ 0 ] [ ] ,
236+ fields : FieldDef [ ] ,
189237 ctx : CodecGeneratorContext ,
190238) => {
191239 const properties = fields . map ( ( field ) => generateTsObjectField ( field , ctx ) ) ;
192240 return `{\n${ properties . join ( "\n" ) } \n${ ctx . indent } }` ;
193241} ;
194242
195243export const generateTsObjectField = (
196- field : { name : string ; cardinality : Cardinality ; codec : ICodec } ,
244+ field : FieldDef ,
197245 ctx : CodecGeneratorContext ,
198246) => {
199- const codec = unwrapSetCodec ( field . codec , field . cardinality ) ;
247+ const codec = unwrapSetCodec ( field ) ;
200248
201249 const name = JSON . stringify ( field . name ) ;
202250 const value = ctx . applyCardinality (
@@ -210,15 +258,15 @@ export const generateTsObjectField = (
210258 return `${ ctx . indent } ${ isReadonly } ${ name } ${ questionMark } : ${ value } ;` ;
211259} ;
212260
213- function unwrapSetCodec ( codec : ICodec , cardinality : Cardinality ) {
214- if ( ! ( codec instanceof SetCodec ) ) {
215- return codec ;
261+ function unwrapSetCodec ( field : FieldDef ) {
262+ if ( ! ( field . codec instanceof SetCodec ) ) {
263+ return field . codec ;
216264 }
217265 if (
218- cardinality === Cardinality . Many ||
219- cardinality === Cardinality . AtLeastOne
266+ field . cardinality === Cardinality . Many ||
267+ field . cardinality === Cardinality . AtLeastOne
220268 ) {
221- return codec . getSubcodecs ( ) [ 0 ] ;
269+ return field . codec . getSubcodecs ( ) [ 0 ] ;
222270 }
223271 throw new Error ( "Sub-codec is SetCodec, but upper cardinality is one" ) ;
224272}
0 commit comments