@@ -72,6 +72,8 @@ struct BridgeJSLink {
72
72
var namespacedEnums : [ ExportedEnum ] = [ ]
73
73
var enumConstantLines : [ String ] = [ ]
74
74
var dtsEnumLines : [ String ] = [ ]
75
+ var topLevelEnumLines : [ String ] = [ ]
76
+ var topLevelDtsEnumLines : [ String ] = [ ]
75
77
76
78
if exportedSkeletons. contains ( where: { $0. classes. count > 0 } ) {
77
79
classLines. append (
@@ -102,14 +104,31 @@ struct BridgeJSLink {
102
104
if !skeleton. enums. isEmpty {
103
105
for enumDefinition in skeleton. enums {
104
106
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
+ // ALL case and raw value enums become top-level exports
113
+ var exportedJsEnum = jsEnum
114
+ if !exportedJsEnum. isEmpty && exportedJsEnum [ 0 ] . hasPrefix ( " const " ) {
115
+ exportedJsEnum [ 0 ] = " export " + exportedJsEnum[ 0 ]
116
+ }
117
+ topLevelEnumLines. append ( contentsOf: exportedJsEnum)
118
+ topLevelDtsEnumLines. append ( contentsOf: dtsEnum)
119
+
120
+ // Track namespaced enums for globalThis assignments
121
+ if enumDefinition. namespace != nil {
122
+ namespacedEnums. append ( enumDefinition)
123
+ }
124
+ case . associatedValue:
125
+ enumConstantLines. append ( contentsOf: jsEnum)
107
126
exportsLines. append ( " \( enumDefinition. name) , " )
108
127
if enumDefinition. namespace != nil {
109
128
namespacedEnums. append ( enumDefinition)
110
129
}
130
+ dtsEnumLines. append ( contentsOf: dtsEnum)
111
131
}
112
- dtsEnumLines. append ( contentsOf: dtsEnum)
113
132
}
114
133
}
115
134
@@ -153,10 +172,13 @@ struct BridgeJSLink {
153
172
154
173
let exportsSection : String
155
174
if hasNamespacedItems {
175
+ // Only pass associated value enums to renderGlobalNamespace
176
+ // (case and raw value enums are handled at top-level)
177
+ let namespacedEnumsForExports = namespacedEnums. filter { $0. enumType == . associatedValue }
156
178
let namespaceSetupCode = namespaceBuilder. renderGlobalNamespace (
157
179
namespacedFunctions: namespacedFunctions,
158
180
namespacedClasses: namespacedClasses,
159
- namespacedEnums: namespacedEnums
181
+ namespacedEnums: namespacedEnumsForExports
160
182
)
161
183
. map { $0. indent ( count: 12 ) } . joined ( separator: " \n " )
162
184
@@ -189,14 +211,22 @@ struct BridgeJSLink {
189
211
"""
190
212
}
191
213
214
+ let topLevelEnumsSection = topLevelEnumLines. isEmpty ? " " : topLevelEnumLines. joined ( separator: " \n " ) + " \n \n "
215
+
216
+ let topLevelNamespaceCode = namespaceBuilder. renderTopLevelEnumNamespaceAssignments (
217
+ namespacedEnums: namespacedEnums
218
+ )
219
+ let namespaceAssignmentsSection =
220
+ topLevelNamespaceCode. isEmpty ? " " : topLevelNamespaceCode. joined ( separator: " \n " ) + " \n \n "
221
+
192
222
let outputJs = """
193
223
// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit,
194
224
// DO NOT EDIT.
195
225
//
196
226
// To update this file, just rebuild your project or run
197
227
// `swift package bridge-js`.
198
228
199
- export async function createInstantiator(options, swift) {
229
+ \( topLevelEnumsSection ) \( namespaceAssignmentsSection ) export async function createInstantiator(options, swift) {
200
230
let instance;
201
231
let memory;
202
232
let setException;
@@ -270,14 +300,17 @@ struct BridgeJSLink {
270
300
dtsLines. append ( " export type Imports = { " )
271
301
dtsLines. append ( contentsOf: importObjectBuilders. flatMap { $0. dtsImportLines } . map { $0. indent ( count: 4 ) } )
272
302
dtsLines. append ( " } " )
303
+ let topLevelDtsEnumsSection =
304
+ topLevelDtsEnumLines. isEmpty ? " " : topLevelDtsEnumLines. joined ( separator: " \n " ) + " \n "
305
+
273
306
let outputDts = """
274
307
// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit,
275
308
// DO NOT EDIT.
276
309
//
277
310
// To update this file, just rebuild your project or run
278
311
// `swift package bridge-js`.
279
312
280
- \( dtsLines. joined ( separator: " \n " ) )
313
+ \( topLevelDtsEnumsSection ) \( dtsLines. joined ( separator: " \n " ) )
281
314
export function createInstantiator(options: {
282
315
imports: Imports;
283
316
}, swift: any): Promise<{
@@ -535,7 +568,7 @@ struct BridgeJSLink {
535
568
jsLines. append ( " const \( enumDefinition. name) = { " )
536
569
for (index, enumCase) in enumDefinition. cases. enumerated ( ) {
537
570
let caseName = enumCase. name. capitalizedFirstLetter
538
- jsLines. append ( " \( caseName) : \( index) , " . indent ( count: 0 ) )
571
+ jsLines. append ( " \( caseName) : \( index) , " . indent ( count: 4 ) )
539
572
}
540
573
jsLines. append ( " }; " )
541
574
jsLines. append ( " " )
@@ -546,15 +579,15 @@ struct BridgeJSLink {
546
579
dtsLines. append ( " export enum \( enumDefinition. name) { " )
547
580
for (index, enumCase) in enumDefinition. cases. enumerated ( ) {
548
581
let caseName = enumCase. name. capitalizedFirstLetter
549
- dtsLines. append ( " \( caseName) = \( index) , " )
582
+ dtsLines. append ( " \( caseName) = \( index) , " . indent ( count : 4 ) )
550
583
}
551
584
dtsLines. append ( " } " )
552
585
dtsLines. append ( " " )
553
586
case . const:
554
587
dtsLines. append ( " export const \( enumDefinition. name) : { " )
555
588
for (index, enumCase) in enumDefinition. cases. enumerated ( ) {
556
589
let caseName = enumCase. name. capitalizedFirstLetter
557
- dtsLines. append ( " readonly \( caseName) : \( index) ; " )
590
+ dtsLines. append ( " readonly \( caseName) : \( index) ; " . indent ( count : 4 ) )
558
591
}
559
592
dtsLines. append ( " }; " )
560
593
dtsLines. append (
@@ -608,7 +641,7 @@ struct BridgeJSLink {
608
641
case " Float " , " Double " : formattedValue = rawValue
609
642
default : formattedValue = rawValue
610
643
}
611
- dtsLines. append ( " \( caseName) = \( formattedValue) , " )
644
+ dtsLines. append ( " \( caseName) = \( formattedValue) , " . indent ( count : 4 ) )
612
645
}
613
646
dtsLines. append ( " } " )
614
647
dtsLines. append ( " " )
@@ -630,7 +663,7 @@ struct BridgeJSLink {
630
663
formattedValue = rawValue
631
664
}
632
665
633
- dtsLines. append ( " readonly \( caseName) : \( formattedValue) ; " )
666
+ dtsLines. append ( " readonly \( caseName) : \( formattedValue) ; " . indent ( count : 4 ) )
634
667
}
635
668
dtsLines. append ( " }; " )
636
669
dtsLines. append (
@@ -780,7 +813,7 @@ struct BridgeJSLink {
780
813
781
814
uniqueNamespaces. sorted ( ) . forEach { namespace in
782
815
lines. append ( " if (typeof globalThis. \( namespace) === 'undefined') { " )
783
- lines. append ( " globalThis.\( namespace) = {}; " )
816
+ lines. append ( " globalThis. \( namespace) = {}; " . indent ( count : 4 ) )
784
817
lines. append ( " } " )
785
818
}
786
819
@@ -790,8 +823,11 @@ struct BridgeJSLink {
790
823
}
791
824
792
825
namespacedEnums. forEach { enumDefinition in
793
- let namespacePath : String = enumDefinition. namespace? . joined ( separator: " . " ) ?? " "
794
- lines. append ( " globalThis. \( namespacePath) . \( enumDefinition. name) = exports. \( enumDefinition. name) ; " )
826
+ // Only handle associated value enums here (case and raw value enums are handled at top-level)
827
+ if enumDefinition. enumType == . associatedValue {
828
+ let namespacePath : String = enumDefinition. namespace? . joined ( separator: " . " ) ?? " "
829
+ lines. append ( " globalThis. \( namespacePath) . \( enumDefinition. name) = exports. \( enumDefinition. name) ; " )
830
+ }
795
831
}
796
832
797
833
namespacedFunctions. forEach { function in
@@ -1015,7 +1051,7 @@ struct BridgeJSLink {
1015
1051
1016
1052
uniqueNamespaces. sorted ( ) . forEach { namespace in
1017
1053
lines. append ( " if (typeof globalThis. \( namespace) === 'undefined') { " )
1018
- lines. append ( " globalThis.\( namespace) = {}; " )
1054
+ lines. append ( " globalThis. \( namespace) = {}; " . indent ( count : 4 ) )
1019
1055
lines. append ( " } " )
1020
1056
}
1021
1057
@@ -1037,6 +1073,44 @@ struct BridgeJSLink {
1037
1073
return lines
1038
1074
}
1039
1075
1076
+ func renderTopLevelEnumNamespaceAssignments( namespacedEnums: [ ExportedEnum ] ) -> [ String ] {
1077
+ let topLevelNamespacedEnums = namespacedEnums. filter { $0. enumType == . simple || $0. enumType == . rawValue }
1078
+
1079
+ guard !topLevelNamespacedEnums. isEmpty else { return [ ] }
1080
+
1081
+ var lines : [ String ] = [ ]
1082
+ var uniqueNamespaces : [ String ] = [ ]
1083
+ var seen = Set < String > ( )
1084
+
1085
+ for enumDef in topLevelNamespacedEnums {
1086
+ guard let namespacePath = enumDef. namespace else { continue }
1087
+ namespacePath. enumerated ( ) . forEach { ( index, _) in
1088
+ let path = namespacePath [ 0 ... index] . joined ( separator: " . " )
1089
+ if !seen. contains ( path) {
1090
+ seen. insert ( path)
1091
+ uniqueNamespaces. append ( path)
1092
+ }
1093
+ }
1094
+ }
1095
+
1096
+ for namespace in uniqueNamespaces {
1097
+ lines. append ( " if (typeof globalThis. \( namespace) === 'undefined') { " )
1098
+ lines. append ( " globalThis. \( namespace) = {}; " . indent ( count: 4 ) )
1099
+ lines. append ( " } " )
1100
+ }
1101
+
1102
+ if !lines. isEmpty {
1103
+ lines. append ( " " )
1104
+ }
1105
+
1106
+ for enumDef in topLevelNamespacedEnums {
1107
+ let namespacePath = enumDef. namespace? . joined ( separator: " . " ) ?? " "
1108
+ lines. append ( " globalThis. \( namespacePath) . \( enumDef. name) = \( enumDef. name) ; " )
1109
+ }
1110
+
1111
+ return lines
1112
+ }
1113
+
1040
1114
private struct NamespaceContent {
1041
1115
var functions : [ ExportedFunction ] = [ ]
1042
1116
var classes : [ ExportedClass ] = [ ]
0 commit comments