@@ -72,6 +72,8 @@ struct BridgeJSLink {
7272 var namespacedEnums : [ ExportedEnum ] = [ ]
7373 var enumConstantLines : [ String ] = [ ]
7474 var dtsEnumLines : [ String ] = [ ]
75+ var topLevelEnumLines : [ String ] = [ ]
76+ var topLevelDtsEnumLines : [ String ] = [ ]
7577
7678 if exportedSkeletons. contains ( where: { $0. classes. count > 0 } ) {
7779 classLines. append (
@@ -102,14 +104,29 @@ struct BridgeJSLink {
102104 if !skeleton. enums. isEmpty {
103105 for enumDefinition in skeleton. enums {
104106 let ( jsEnum, dtsEnum) = try renderExportedEnum ( enumDefinition)
105- enumConstantLines. append ( contentsOf: jsEnum)
106- if enumDefinition. enumType != . namespace {
107+
108+ switch enumDefinition. enumType {
109+ case . namespace:
110+ break
111+ case . simple, . rawValue:
112+ var exportedJsEnum = jsEnum
113+ if !exportedJsEnum. isEmpty && exportedJsEnum [ 0 ] . hasPrefix ( " const " ) {
114+ exportedJsEnum [ 0 ] = " export " + exportedJsEnum[ 0 ]
115+ }
116+ topLevelEnumLines. append ( contentsOf: exportedJsEnum)
117+ topLevelDtsEnumLines. append ( contentsOf: dtsEnum)
118+
119+ if enumDefinition. namespace != nil {
120+ namespacedEnums. append ( enumDefinition)
121+ }
122+ case . associatedValue:
123+ enumConstantLines. append ( contentsOf: jsEnum)
107124 exportsLines. append ( " \( enumDefinition. name) , " )
108125 if enumDefinition. namespace != nil {
109126 namespacedEnums. append ( enumDefinition)
110127 }
128+ dtsEnumLines. append ( contentsOf: dtsEnum)
111129 }
112- dtsEnumLines. append ( contentsOf: dtsEnum)
113130 }
114131 }
115132
@@ -153,10 +170,11 @@ struct BridgeJSLink {
153170
154171 let exportsSection : String
155172 if hasNamespacedItems {
173+ let namespacedEnumsForExports = namespacedEnums. filter { $0. enumType == . associatedValue }
156174 let namespaceSetupCode = namespaceBuilder. renderGlobalNamespace (
157175 namespacedFunctions: namespacedFunctions,
158176 namespacedClasses: namespacedClasses,
159- namespacedEnums: namespacedEnums
177+ namespacedEnums: namespacedEnumsForExports
160178 )
161179 . map { $0. indent ( count: 12 ) } . joined ( separator: " \n " )
162180
@@ -189,14 +207,22 @@ struct BridgeJSLink {
189207 """
190208 }
191209
210+ let topLevelEnumsSection = topLevelEnumLines. isEmpty ? " " : topLevelEnumLines. joined ( separator: " \n " ) + " \n \n "
211+
212+ let topLevelNamespaceCode = namespaceBuilder. renderTopLevelEnumNamespaceAssignments (
213+ namespacedEnums: namespacedEnums
214+ )
215+ let namespaceAssignmentsSection =
216+ topLevelNamespaceCode. isEmpty ? " " : topLevelNamespaceCode. joined ( separator: " \n " ) + " \n \n "
217+
192218 let outputJs = """
193219 // NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit,
194220 // DO NOT EDIT.
195221 //
196222 // To update this file, just rebuild your project or run
197223 // `swift package bridge-js`.
198224
199- export async function createInstantiator(options, swift) {
225+ \( topLevelEnumsSection ) \( namespaceAssignmentsSection ) export async function createInstantiator(options, swift) {
200226 let instance;
201227 let memory;
202228 let setException;
@@ -270,14 +296,17 @@ struct BridgeJSLink {
270296 dtsLines. append ( " export type Imports = { " )
271297 dtsLines. append ( contentsOf: importObjectBuilders. flatMap { $0. dtsImportLines } . map { $0. indent ( count: 4 ) } )
272298 dtsLines. append ( " } " )
299+ let topLevelDtsEnumsSection =
300+ topLevelDtsEnumLines. isEmpty ? " " : topLevelDtsEnumLines. joined ( separator: " \n " ) + " \n "
301+
273302 let outputDts = """
274303 // NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit,
275304 // DO NOT EDIT.
276305 //
277306 // To update this file, just rebuild your project or run
278307 // `swift package bridge-js`.
279308
280- \( dtsLines. joined ( separator: " \n " ) )
309+ \( topLevelDtsEnumsSection ) \( dtsLines. joined ( separator: " \n " ) )
281310 export function createInstantiator(options: {
282311 imports: Imports;
283312 }, swift: any): Promise<{
@@ -535,7 +564,7 @@ struct BridgeJSLink {
535564 jsLines. append ( " const \( enumDefinition. name) = { " )
536565 for (index, enumCase) in enumDefinition. cases. enumerated ( ) {
537566 let caseName = enumCase. name. capitalizedFirstLetter
538- jsLines. append ( " \( caseName) : \( index) , " . indent ( count: 0 ) )
567+ jsLines. append ( " \( caseName) : \( index) , " . indent ( count: 4 ) )
539568 }
540569 jsLines. append ( " }; " )
541570 jsLines. append ( " " )
@@ -546,15 +575,15 @@ struct BridgeJSLink {
546575 dtsLines. append ( " export enum \( enumDefinition. name) { " )
547576 for (index, enumCase) in enumDefinition. cases. enumerated ( ) {
548577 let caseName = enumCase. name. capitalizedFirstLetter
549- dtsLines. append ( " \( caseName) = \( index) , " )
578+ dtsLines. append ( " \( caseName) = \( index) , " . indent ( count : 4 ) )
550579 }
551580 dtsLines. append ( " } " )
552581 dtsLines. append ( " " )
553582 case . const:
554583 dtsLines. append ( " export const \( enumDefinition. name) : { " )
555584 for (index, enumCase) in enumDefinition. cases. enumerated ( ) {
556585 let caseName = enumCase. name. capitalizedFirstLetter
557- dtsLines. append ( " readonly \( caseName) : \( index) ; " )
586+ dtsLines. append ( " readonly \( caseName) : \( index) ; " . indent ( count : 4 ) )
558587 }
559588 dtsLines. append ( " }; " )
560589 dtsLines. append (
@@ -608,7 +637,7 @@ struct BridgeJSLink {
608637 case " Float " , " Double " : formattedValue = rawValue
609638 default : formattedValue = rawValue
610639 }
611- dtsLines. append ( " \( caseName) = \( formattedValue) , " )
640+ dtsLines. append ( " \( caseName) = \( formattedValue) , " . indent ( count : 4 ) )
612641 }
613642 dtsLines. append ( " } " )
614643 dtsLines. append ( " " )
@@ -630,7 +659,7 @@ struct BridgeJSLink {
630659 formattedValue = rawValue
631660 }
632661
633- dtsLines. append ( " readonly \( caseName) : \( formattedValue) ; " )
662+ dtsLines. append ( " readonly \( caseName) : \( formattedValue) ; " . indent ( count : 4 ) )
634663 }
635664 dtsLines. append ( " }; " )
636665 dtsLines. append (
@@ -780,7 +809,7 @@ struct BridgeJSLink {
780809
781810 uniqueNamespaces. sorted ( ) . forEach { namespace in
782811 lines. append ( " if (typeof globalThis. \( namespace) === 'undefined') { " )
783- lines. append ( " globalThis.\( namespace) = {}; " )
812+ lines. append ( " globalThis. \( namespace) = {}; " . indent ( count : 4 ) )
784813 lines. append ( " } " )
785814 }
786815
@@ -790,8 +819,10 @@ struct BridgeJSLink {
790819 }
791820
792821 namespacedEnums. forEach { enumDefinition in
793- let namespacePath : String = enumDefinition. namespace? . joined ( separator: " . " ) ?? " "
794- lines. append ( " globalThis. \( namespacePath) . \( enumDefinition. name) = exports. \( enumDefinition. name) ; " )
822+ if enumDefinition. enumType == . associatedValue {
823+ let namespacePath : String = enumDefinition. namespace? . joined ( separator: " . " ) ?? " "
824+ lines. append ( " globalThis. \( namespacePath) . \( enumDefinition. name) = exports. \( enumDefinition. name) ; " )
825+ }
795826 }
796827
797828 namespacedFunctions. forEach { function in
@@ -1015,7 +1046,7 @@ struct BridgeJSLink {
10151046
10161047 uniqueNamespaces. sorted ( ) . forEach { namespace in
10171048 lines. append ( " if (typeof globalThis. \( namespace) === 'undefined') { " )
1018- lines. append ( " globalThis.\( namespace) = {}; " )
1049+ lines. append ( " globalThis. \( namespace) = {}; " . indent ( count : 4 ) )
10191050 lines. append ( " } " )
10201051 }
10211052
@@ -1037,6 +1068,44 @@ struct BridgeJSLink {
10371068 return lines
10381069 }
10391070
1071+ func renderTopLevelEnumNamespaceAssignments( namespacedEnums: [ ExportedEnum ] ) -> [ String ] {
1072+ let topLevelNamespacedEnums = namespacedEnums. filter { $0. enumType == . simple || $0. enumType == . rawValue }
1073+
1074+ guard !topLevelNamespacedEnums. isEmpty else { return [ ] }
1075+
1076+ var lines : [ String ] = [ ]
1077+ var uniqueNamespaces : [ String ] = [ ]
1078+ var seen = Set < String > ( )
1079+
1080+ for enumDef in topLevelNamespacedEnums {
1081+ guard let namespacePath = enumDef. namespace else { continue }
1082+ namespacePath. enumerated ( ) . forEach { ( index, _) in
1083+ let path = namespacePath [ 0 ... index] . joined ( separator: " . " )
1084+ if !seen. contains ( path) {
1085+ seen. insert ( path)
1086+ uniqueNamespaces. append ( path)
1087+ }
1088+ }
1089+ }
1090+
1091+ for namespace in uniqueNamespaces {
1092+ lines. append ( " if (typeof globalThis. \( namespace) === 'undefined') { " )
1093+ lines. append ( " globalThis. \( namespace) = {}; " . indent ( count: 4 ) )
1094+ lines. append ( " } " )
1095+ }
1096+
1097+ if !lines. isEmpty {
1098+ lines. append ( " " )
1099+ }
1100+
1101+ for enumDef in topLevelNamespacedEnums {
1102+ let namespacePath = enumDef. namespace? . joined ( separator: " . " ) ?? " "
1103+ lines. append ( " globalThis. \( namespacePath) . \( enumDef. name) = \( enumDef. name) ; " )
1104+ }
1105+
1106+ return lines
1107+ }
1108+
10401109 private struct NamespaceContent {
10411110 var functions : [ ExportedFunction ] = [ ]
10421111 var classes : [ ExportedClass ] = [ ]
@@ -1410,7 +1479,9 @@ extension String {
14101479 func indent( count: Int ) -> String {
14111480 return String ( repeating: " " , count: count) + self
14121481 }
1482+ }
14131483
1484+ fileprivate extension String {
14141485 var capitalizedFirstLetter : String {
14151486 guard !isEmpty else { return self }
14161487 return prefix ( 1 ) . uppercased ( ) + dropFirst( )
0 commit comments