goscript 0.0.26 → 0.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/README.md +4 -4
  2. package/cmd/goscript/cmd_compile.go +0 -3
  3. package/cmd/goscript/deps.go +11 -0
  4. package/compiler/analysis.go +298 -55
  5. package/compiler/assignment.go +2 -2
  6. package/compiler/builtin_test.go +1 -1
  7. package/compiler/compiler.go +200 -68
  8. package/compiler/compiler_test.go +17 -24
  9. package/compiler/composite-lit.go +32 -8
  10. package/compiler/decl.go +6 -6
  11. package/compiler/expr-call.go +170 -15
  12. package/compiler/expr-selector.go +100 -0
  13. package/compiler/expr.go +1 -1
  14. package/compiler/protobuf.go +557 -0
  15. package/compiler/spec-struct.go +4 -0
  16. package/compiler/spec-value.go +89 -10
  17. package/compiler/spec.go +254 -1
  18. package/compiler/stmt-assign.go +35 -0
  19. package/compiler/type-assert.go +87 -0
  20. package/compiler/type.go +4 -1
  21. package/dist/gs/builtin/builtin.d.ts +20 -1
  22. package/dist/gs/builtin/builtin.js +95 -4
  23. package/dist/gs/builtin/builtin.js.map +1 -1
  24. package/dist/gs/builtin/slice.d.ts +1 -1
  25. package/dist/gs/builtin/slice.js +21 -2
  26. package/dist/gs/builtin/slice.js.map +1 -1
  27. package/dist/gs/errors/errors.d.ts +5 -6
  28. package/dist/gs/errors/errors.js.map +1 -1
  29. package/dist/gs/internal/oserror/errors.d.ts +6 -0
  30. package/dist/gs/internal/oserror/errors.js +7 -0
  31. package/dist/gs/internal/oserror/errors.js.map +1 -0
  32. package/dist/gs/internal/oserror/index.d.ts +1 -0
  33. package/dist/gs/internal/oserror/index.js +2 -0
  34. package/dist/gs/internal/oserror/index.js.map +1 -0
  35. package/dist/gs/io/fs/format.d.ts +3 -0
  36. package/dist/gs/io/fs/format.js +56 -0
  37. package/dist/gs/io/fs/format.js.map +1 -0
  38. package/dist/gs/io/fs/fs.d.ts +79 -0
  39. package/dist/gs/io/fs/fs.js +200 -0
  40. package/dist/gs/io/fs/fs.js.map +1 -0
  41. package/dist/gs/io/fs/glob.d.ts +10 -0
  42. package/dist/gs/io/fs/glob.js +141 -0
  43. package/dist/gs/io/fs/glob.js.map +1 -0
  44. package/dist/gs/io/fs/index.d.ts +8 -0
  45. package/dist/gs/io/fs/index.js +9 -0
  46. package/dist/gs/io/fs/index.js.map +1 -0
  47. package/dist/gs/io/fs/readdir.d.ts +7 -0
  48. package/dist/gs/io/fs/readdir.js +152 -0
  49. package/dist/gs/io/fs/readdir.js.map +1 -0
  50. package/dist/gs/io/fs/readfile.d.ts +6 -0
  51. package/dist/gs/io/fs/readfile.js +118 -0
  52. package/dist/gs/io/fs/readfile.js.map +1 -0
  53. package/dist/gs/io/fs/stat.d.ts +6 -0
  54. package/dist/gs/io/fs/stat.js +87 -0
  55. package/dist/gs/io/fs/stat.js.map +1 -0
  56. package/dist/gs/io/fs/sub.d.ts +6 -0
  57. package/dist/gs/io/fs/sub.js +172 -0
  58. package/dist/gs/io/fs/sub.js.map +1 -0
  59. package/dist/gs/io/fs/walk.d.ts +7 -0
  60. package/dist/gs/io/fs/walk.js +76 -0
  61. package/dist/gs/io/fs/walk.js.map +1 -0
  62. package/dist/gs/io/index.d.ts +1 -0
  63. package/dist/gs/io/index.js +2 -0
  64. package/dist/gs/io/index.js.map +1 -0
  65. package/dist/gs/io/io.d.ts +107 -0
  66. package/dist/gs/io/io.js +385 -0
  67. package/dist/gs/io/io.js.map +1 -0
  68. package/dist/gs/path/index.d.ts +2 -0
  69. package/dist/gs/path/index.js +3 -0
  70. package/dist/gs/path/index.js.map +1 -0
  71. package/dist/gs/path/match.d.ts +6 -0
  72. package/dist/gs/path/match.js +281 -0
  73. package/dist/gs/path/match.js.map +1 -0
  74. package/dist/gs/path/path.d.ts +7 -0
  75. package/dist/gs/path/path.js +256 -0
  76. package/dist/gs/path/path.js.map +1 -0
  77. package/dist/gs/strings/builder.d.ts +18 -0
  78. package/dist/gs/strings/builder.js +205 -0
  79. package/dist/gs/strings/builder.js.map +1 -0
  80. package/dist/gs/strings/clone.d.ts +1 -0
  81. package/dist/gs/strings/clone.js +16 -0
  82. package/dist/gs/strings/clone.js.map +1 -0
  83. package/dist/gs/strings/compare.d.ts +1 -0
  84. package/dist/gs/strings/compare.js +14 -0
  85. package/dist/gs/strings/compare.js.map +1 -0
  86. package/dist/gs/strings/index.d.ts +2 -0
  87. package/dist/gs/strings/index.js +3 -0
  88. package/dist/gs/strings/index.js.map +1 -0
  89. package/dist/gs/strings/iter.d.ts +8 -0
  90. package/dist/gs/strings/iter.js +160 -0
  91. package/dist/gs/strings/iter.js.map +1 -0
  92. package/dist/gs/strings/reader.d.ts +34 -0
  93. package/dist/gs/strings/reader.js +418 -0
  94. package/dist/gs/strings/reader.js.map +1 -0
  95. package/dist/gs/strings/replace.d.ts +106 -0
  96. package/dist/gs/strings/replace.js +1136 -0
  97. package/dist/gs/strings/replace.js.map +1 -0
  98. package/dist/gs/strings/search.d.ts +24 -0
  99. package/dist/gs/strings/search.js +169 -0
  100. package/dist/gs/strings/search.js.map +1 -0
  101. package/dist/gs/strings/strings.d.ts +47 -0
  102. package/dist/gs/strings/strings.js +418 -0
  103. package/dist/gs/strings/strings.js.map +1 -0
  104. package/dist/gs/stringslite/index.d.ts +1 -0
  105. package/dist/gs/stringslite/index.js +2 -0
  106. package/dist/gs/stringslite/index.js.map +1 -0
  107. package/dist/gs/stringslite/strings.d.ts +11 -0
  108. package/dist/gs/stringslite/strings.js +67 -0
  109. package/dist/gs/stringslite/strings.js.map +1 -0
  110. package/dist/gs/sync/index.d.ts +1 -0
  111. package/dist/gs/sync/index.js +2 -0
  112. package/dist/gs/sync/index.js.map +1 -0
  113. package/dist/gs/sync/sync.d.ts +79 -0
  114. package/dist/gs/sync/sync.js +392 -0
  115. package/dist/gs/sync/sync.js.map +1 -0
  116. package/dist/gs/time/time.d.ts +11 -2
  117. package/dist/gs/time/time.js +337 -12
  118. package/dist/gs/time/time.js.map +1 -1
  119. package/dist/gs/unicode/index.d.ts +1 -0
  120. package/dist/gs/unicode/index.js +2 -0
  121. package/dist/gs/unicode/index.js.map +1 -0
  122. package/dist/gs/unicode/unicode.d.ts +105 -0
  123. package/dist/gs/unicode/unicode.js +332 -0
  124. package/dist/gs/unicode/unicode.js.map +1 -0
  125. package/dist/gs/unicode/utf8/index.d.ts +1 -0
  126. package/dist/gs/unicode/utf8/index.js +3 -0
  127. package/dist/gs/unicode/utf8/index.js.map +1 -0
  128. package/dist/gs/unicode/utf8/utf8.d.ts +20 -0
  129. package/dist/gs/unicode/utf8/utf8.js +196 -0
  130. package/dist/gs/unicode/utf8/utf8.js.map +1 -0
  131. package/dist/gs/unsafe/index.d.ts +1 -0
  132. package/dist/gs/unsafe/index.js +2 -0
  133. package/dist/gs/unsafe/index.js.map +1 -0
  134. package/dist/gs/unsafe/unsafe.d.ts +11 -0
  135. package/dist/gs/unsafe/unsafe.js +44 -0
  136. package/dist/gs/unsafe/unsafe.js.map +1 -0
  137. package/go.mod +2 -1
  138. package/go.sum +6 -2
  139. package/gs/README.md +6 -0
  140. package/gs/builtin/builtin.ts +171 -0
  141. package/gs/builtin/channel.ts +683 -0
  142. package/gs/builtin/defer.ts +58 -0
  143. package/gs/builtin/index.ts +1 -0
  144. package/gs/builtin/io.ts +22 -0
  145. package/gs/builtin/map.ts +50 -0
  146. package/gs/builtin/slice.ts +1030 -0
  147. package/gs/builtin/type.ts +1106 -0
  148. package/gs/builtin/varRef.ts +25 -0
  149. package/gs/cmp/godoc.txt +8 -0
  150. package/gs/cmp/index.ts +29 -0
  151. package/gs/context/context.ts +401 -0
  152. package/gs/context/godoc.txt +69 -0
  153. package/gs/context/index.ts +1 -0
  154. package/gs/errors/errors.ts +223 -0
  155. package/gs/errors/godoc.txt +63 -0
  156. package/gs/errors/index.ts +1 -0
  157. package/gs/internal/goarch/godoc.txt +39 -0
  158. package/gs/internal/goarch/index.ts +18 -0
  159. package/gs/internal/oserror/errors.ts +14 -0
  160. package/gs/internal/oserror/index.ts +1 -0
  161. package/gs/io/fs/format.ts +65 -0
  162. package/gs/io/fs/fs.ts +359 -0
  163. package/gs/io/fs/glob.ts +167 -0
  164. package/gs/io/fs/godoc.txt +35 -0
  165. package/gs/io/fs/index.ts +8 -0
  166. package/gs/io/fs/readdir.ts +126 -0
  167. package/gs/io/fs/readfile.ts +77 -0
  168. package/gs/io/fs/stat.ts +38 -0
  169. package/gs/io/fs/sub.ts +208 -0
  170. package/gs/io/fs/walk.ts +89 -0
  171. package/gs/io/godoc.txt +61 -0
  172. package/gs/io/index.ts +1 -0
  173. package/gs/io/io.go +75 -0
  174. package/gs/io/io.ts +546 -0
  175. package/gs/iter/godoc.txt +203 -0
  176. package/gs/iter/index.ts +1 -0
  177. package/gs/iter/iter.ts +117 -0
  178. package/gs/math/bits/index.ts +356 -0
  179. package/gs/math/godoc.txt +76 -0
  180. package/gs/path/index.ts +2 -0
  181. package/gs/path/match.ts +307 -0
  182. package/gs/path/path.ts +301 -0
  183. package/gs/runtime/godoc.txt +331 -0
  184. package/gs/runtime/index.ts +1 -0
  185. package/gs/runtime/runtime.ts +178 -0
  186. package/gs/slices/godoc.txt +44 -0
  187. package/gs/slices/index.ts +1 -0
  188. package/gs/slices/slices.ts +22 -0
  189. package/gs/strings/builder.test.ts +121 -0
  190. package/gs/strings/builder.ts +223 -0
  191. package/gs/strings/clone.test.ts +43 -0
  192. package/gs/strings/clone.ts +17 -0
  193. package/gs/strings/compare.test.ts +84 -0
  194. package/gs/strings/compare.ts +13 -0
  195. package/gs/strings/godoc.txt +66 -0
  196. package/gs/strings/index.ts +2 -0
  197. package/gs/strings/iter.test.ts +343 -0
  198. package/gs/strings/iter.ts +171 -0
  199. package/gs/strings/reader.test.ts +242 -0
  200. package/gs/strings/reader.ts +451 -0
  201. package/gs/strings/replace.test.ts +181 -0
  202. package/gs/strings/replace.ts +1310 -0
  203. package/gs/strings/search.test.ts +214 -0
  204. package/gs/strings/search.ts +213 -0
  205. package/gs/strings/strings.test.ts +477 -0
  206. package/gs/strings/strings.ts +510 -0
  207. package/gs/stringslite/godoc.txt +17 -0
  208. package/gs/stringslite/index.ts +1 -0
  209. package/gs/stringslite/strings.ts +82 -0
  210. package/gs/sync/godoc.txt +21 -0
  211. package/gs/sync/index.ts +1 -0
  212. package/gs/sync/sync.go +64 -0
  213. package/gs/sync/sync.ts +449 -0
  214. package/gs/time/godoc.txt +116 -0
  215. package/gs/time/index.ts +1 -0
  216. package/gs/time/time.ts +585 -0
  217. package/gs/unicode/godoc.txt +52 -0
  218. package/gs/unicode/index.ts +1 -0
  219. package/gs/unicode/unicode.go +38 -0
  220. package/gs/unicode/unicode.ts +418 -0
  221. package/gs/unicode/utf8/godoc.txt +22 -0
  222. package/gs/unicode/utf8/index.ts +2 -0
  223. package/gs/unicode/utf8/utf8.ts +227 -0
  224. package/gs/unsafe/godoc.txt +19 -0
  225. package/gs/unsafe/index.ts +1 -0
  226. package/gs/unsafe/unsafe.test.ts +68 -0
  227. package/gs/unsafe/unsafe.ts +77 -0
  228. package/package.json +4 -3
package/compiler/spec.go CHANGED
@@ -150,6 +150,237 @@ func (c *GoToTSCompiler) writeClonedFieldInitializer(fieldName string, fieldType
150
150
  c.tsw.WriteLiterally(")")
151
151
  }
152
152
 
153
+ // hasReceiverMethods checks if a type declaration has any receiver methods defined
154
+ func (c *GoToTSCompiler) hasReceiverMethods(typeName string) bool {
155
+ for _, fileSyntax := range c.pkg.Syntax {
156
+ for _, decl := range fileSyntax.Decls {
157
+ funcDecl, isFunc := decl.(*ast.FuncDecl)
158
+ if !isFunc || funcDecl.Recv == nil || len(funcDecl.Recv.List) == 0 {
159
+ continue
160
+ }
161
+ recvField := funcDecl.Recv.List[0]
162
+ recvType := recvField.Type
163
+ if starExpr, ok := recvType.(*ast.StarExpr); ok {
164
+ recvType = starExpr.X
165
+ }
166
+
167
+ // Check for both simple identifiers (FileMode) and generic types (FileMode[T])
168
+ var recvTypeName string
169
+ if ident, ok := recvType.(*ast.Ident); ok {
170
+ recvTypeName = ident.Name
171
+ } else if indexExpr, ok := recvType.(*ast.IndexExpr); ok {
172
+ if ident, ok := indexExpr.X.(*ast.Ident); ok {
173
+ recvTypeName = ident.Name
174
+ }
175
+ }
176
+
177
+ if recvTypeName == typeName {
178
+ return true
179
+ }
180
+ }
181
+ }
182
+ return false
183
+ }
184
+
185
+ // WriteNamedTypeWithMethods generates a TypeScript class for a Go named type that has receiver methods
186
+ func (c *GoToTSCompiler) WriteNamedTypeWithMethods(a *ast.TypeSpec) error {
187
+ className := a.Name.Name
188
+ underlyingType := c.pkg.TypesInfo.TypeOf(a.Type)
189
+
190
+ // Add export for Go-exported types (but not if inside a function)
191
+ isInsideFunction := false
192
+ if nodeInfo := c.analysis.NodeData[a]; nodeInfo != nil {
193
+ isInsideFunction = nodeInfo.IsInsideFunction
194
+ }
195
+
196
+ if a.Name.IsExported() && !isInsideFunction {
197
+ c.tsw.WriteLiterally("export ")
198
+ }
199
+
200
+ c.tsw.WriteLiterallyf("class %s {", className)
201
+ c.tsw.WriteLine("")
202
+ c.tsw.Indent(1)
203
+
204
+ // Constructor that takes the underlying type value
205
+ c.tsw.WriteLiterally("constructor(private _value: ")
206
+ c.WriteGoType(underlyingType, GoTypeContextGeneral)
207
+ c.tsw.WriteLine(") {}")
208
+ c.tsw.WriteLine("")
209
+
210
+ // valueOf method to get the underlying value (for type conversions and operations)
211
+ c.tsw.WriteLiterally("valueOf(): ")
212
+ c.WriteGoType(underlyingType, GoTypeContextGeneral)
213
+ c.tsw.WriteLine(" {")
214
+ c.tsw.Indent(1)
215
+ c.tsw.WriteLine("return this._value")
216
+ c.tsw.Indent(-1)
217
+ c.tsw.WriteLine("}")
218
+ c.tsw.WriteLine("")
219
+
220
+ // toString method for string conversion
221
+ c.tsw.WriteLine("toString(): string {")
222
+ c.tsw.Indent(1)
223
+ c.tsw.WriteLine("return String(this._value)")
224
+ c.tsw.Indent(-1)
225
+ c.tsw.WriteLine("}")
226
+ c.tsw.WriteLine("")
227
+
228
+ // Static from method for type conversion
229
+ c.tsw.WriteLiterallyf("static from(value: ")
230
+ c.WriteGoType(underlyingType, GoTypeContextGeneral)
231
+ c.tsw.WriteLiterallyf("): %s {", className)
232
+ c.tsw.WriteLine("")
233
+ c.tsw.Indent(1)
234
+ c.tsw.WriteLiterallyf("return new %s(value)", className)
235
+ c.tsw.WriteLine("")
236
+ c.tsw.Indent(-1)
237
+ c.tsw.WriteLine("}")
238
+
239
+ // Add receiver methods for this type
240
+ for _, fileSyntax := range c.pkg.Syntax {
241
+ for _, decl := range fileSyntax.Decls {
242
+ funcDecl, isFunc := decl.(*ast.FuncDecl)
243
+ if !isFunc || funcDecl.Recv == nil || len(funcDecl.Recv.List) == 0 {
244
+ continue
245
+ }
246
+ recvField := funcDecl.Recv.List[0]
247
+ recvType := recvField.Type
248
+ if starExpr, ok := recvType.(*ast.StarExpr); ok {
249
+ recvType = starExpr.X
250
+ }
251
+
252
+ // Check for both simple identifiers (FileMode) and generic types (FileMode[T])
253
+ var recvTypeName string
254
+ if ident, ok := recvType.(*ast.Ident); ok {
255
+ recvTypeName = ident.Name
256
+ } else if indexExpr, ok := recvType.(*ast.IndexExpr); ok {
257
+ if ident, ok := indexExpr.X.(*ast.Ident); ok {
258
+ recvTypeName = ident.Name
259
+ }
260
+ }
261
+
262
+ if recvTypeName == className {
263
+ c.tsw.WriteLine("")
264
+ if err := c.writeNamedTypeMethod(funcDecl, className); err != nil {
265
+ return err
266
+ }
267
+ }
268
+ }
269
+ }
270
+
271
+ c.tsw.Indent(-1)
272
+ c.tsw.WriteLine("}")
273
+
274
+ return nil
275
+ }
276
+
277
+ // writeNamedTypeMethod writes a method for a named type, handling receiver binding properly
278
+ func (c *GoToTSCompiler) writeNamedTypeMethod(decl *ast.FuncDecl, className string) error {
279
+ if decl.Doc != nil {
280
+ c.WriteDoc(decl.Doc)
281
+ }
282
+
283
+ // Determine if method is async
284
+ var isAsync bool
285
+ if obj := c.pkg.TypesInfo.Defs[decl.Name]; obj != nil {
286
+ isAsync = c.analysis.IsAsyncFunc(obj)
287
+ }
288
+
289
+ // Methods are typically public in the TS output
290
+ c.tsw.WriteLiterally("public ")
291
+
292
+ // Add async modifier if needed
293
+ if isAsync {
294
+ c.tsw.WriteLiterally("async ")
295
+ }
296
+
297
+ // Keep original Go casing for method names
298
+ if err := c.WriteValueExpr(decl.Name); err != nil { // Method name is a value identifier
299
+ return err
300
+ }
301
+
302
+ // Write signature (parameters and return type)
303
+ funcType := decl.Type
304
+ c.tsw.WriteLiterally("(")
305
+ if funcType.Params != nil {
306
+ c.WriteFieldList(funcType.Params, true) // true = arguments
307
+ }
308
+ c.tsw.WriteLiterally(")")
309
+
310
+ // Handle return type
311
+ if funcType.Results != nil && len(funcType.Results.List) > 0 {
312
+ c.tsw.WriteLiterally(": ")
313
+ if isAsync {
314
+ c.tsw.WriteLiterally("Promise<")
315
+ }
316
+ if len(funcType.Results.List) == 1 {
317
+ // Single return value
318
+ resultType := funcType.Results.List[0].Type
319
+ c.WriteTypeExpr(resultType)
320
+ } else {
321
+ // Multiple return values -> tuple type
322
+ c.tsw.WriteLiterally("[")
323
+ for i, field := range funcType.Results.List {
324
+ if i > 0 {
325
+ c.tsw.WriteLiterally(", ")
326
+ }
327
+ c.WriteTypeExpr(field.Type)
328
+ }
329
+ c.tsw.WriteLiterally("]")
330
+ }
331
+ if isAsync {
332
+ c.tsw.WriteLiterally(">")
333
+ }
334
+ } else {
335
+ // No return value -> void
336
+ if isAsync {
337
+ c.tsw.WriteLiterally(": Promise<void>")
338
+ } else {
339
+ c.tsw.WriteLiterally(": void")
340
+ }
341
+ }
342
+
343
+ c.tsw.WriteLiterally(" ")
344
+
345
+ // For named types with methods, bind receiver name to this._value
346
+ if recvField := decl.Recv.List[0]; len(recvField.Names) > 0 {
347
+ recvName := recvField.Names[0].Name
348
+ if recvName != "_" {
349
+ c.tsw.WriteLine("{")
350
+ c.tsw.Indent(1)
351
+ // Bind the receiver name to this._value for value types
352
+ sanitizedRecvName := c.sanitizeIdentifier(recvName)
353
+ c.tsw.WriteLinef("const %s = this._value", sanitizedRecvName)
354
+
355
+ // Add using statement if needed
356
+ if c.analysis.NeedsDefer(decl.Body) {
357
+ if c.analysis.IsInAsyncFunction(decl) {
358
+ c.tsw.WriteLine("await using __defer = new $.AsyncDisposableStack();")
359
+ } else {
360
+ c.tsw.WriteLine("using cleanup = new $.DisposableStack();")
361
+ }
362
+ }
363
+
364
+ // write method body without outer braces
365
+ for _, stmt := range decl.Body.List {
366
+ if err := c.WriteStmt(stmt); err != nil {
367
+ return fmt.Errorf("failed to write statement in function body: %w", err)
368
+ }
369
+ }
370
+ c.tsw.Indent(-1)
371
+ c.tsw.WriteLine("}")
372
+
373
+ return nil
374
+ }
375
+ }
376
+ // no named receiver, write whole body
377
+ if err := c.WriteStmt(decl.Body); err != nil {
378
+ return fmt.Errorf("failed to write function body: %w", err)
379
+ }
380
+
381
+ return nil
382
+ }
383
+
153
384
  // WriteTypeSpec writes the type specification to the output.
154
385
  func (c *GoToTSCompiler) WriteTypeSpec(a *ast.TypeSpec) error {
155
386
  if a.Doc != nil {
@@ -165,7 +396,20 @@ func (c *GoToTSCompiler) WriteTypeSpec(a *ast.TypeSpec) error {
165
396
  case *ast.InterfaceType:
166
397
  return c.WriteInterfaceTypeSpec(a, t)
167
398
  default:
168
- // type alias
399
+ // Check if this type has receiver methods
400
+ if c.hasReceiverMethods(a.Name.Name) {
401
+ return c.WriteNamedTypeWithMethods(a)
402
+ }
403
+
404
+ // type alias - add export for Go-exported types (but not if inside a function)
405
+ isInsideFunction := false
406
+ if nodeInfo := c.analysis.NodeData[a]; nodeInfo != nil {
407
+ isInsideFunction = nodeInfo.IsInsideFunction
408
+ }
409
+
410
+ if a.Name.IsExported() && !isInsideFunction {
411
+ c.tsw.WriteLiterally("export ")
412
+ }
169
413
  c.tsw.WriteLiterally("type ")
170
414
  if err := c.WriteValueExpr(a.Name); err != nil {
171
415
  return err
@@ -179,6 +423,15 @@ func (c *GoToTSCompiler) WriteTypeSpec(a *ast.TypeSpec) error {
179
423
 
180
424
  // WriteInterfaceTypeSpec writes the TypeScript type for a Go interface type.
181
425
  func (c *GoToTSCompiler) WriteInterfaceTypeSpec(a *ast.TypeSpec, t *ast.InterfaceType) error {
426
+ // Add export for Go-exported interfaces (but not if inside a function)
427
+ isInsideFunction := false
428
+ if nodeInfo := c.analysis.NodeData[a]; nodeInfo != nil {
429
+ isInsideFunction = nodeInfo.IsInsideFunction
430
+ }
431
+
432
+ if a.Name.IsExported() && !isInsideFunction {
433
+ c.tsw.WriteLiterally("export ")
434
+ }
182
435
  c.tsw.WriteLiterally("type ")
183
436
  if err := c.WriteValueExpr(a.Name); err != nil {
184
437
  return err
@@ -384,6 +384,27 @@ func (c *GoToTSCompiler) WriteStmtAssign(exp *ast.AssignStmt) error {
384
384
  // Handle multi-variable assignment from a single expression.
385
385
  if len(exp.Lhs) > 1 && len(exp.Rhs) == 1 {
386
386
  rhsExpr := exp.Rhs[0]
387
+
388
+ // Check for protobuf method calls first
389
+ if callExpr, ok := rhsExpr.(*ast.CallExpr); ok {
390
+ // Handle protobuf MarshalVT: data, err := msg.MarshalVT()
391
+ if len(exp.Lhs) == 2 && c.isProtobufMethodCall(callExpr, "MarshalVT") {
392
+ err := c.writeProtobufMarshalAssignment(exp.Lhs, callExpr, exp.Tok)
393
+ if err != nil {
394
+ return err
395
+ }
396
+ return nil
397
+ }
398
+ // Handle protobuf MarshalJSON: data, err := msg.MarshalJSON()
399
+ if len(exp.Lhs) == 2 && c.isProtobufMethodCall(callExpr, "MarshalJSON") {
400
+ err := c.writeProtobufMarshalJSONAssignment(exp.Lhs, callExpr, exp.Tok)
401
+ if err != nil {
402
+ return err
403
+ }
404
+ return nil
405
+ }
406
+ }
407
+
387
408
  if typeAssertExpr, ok := rhsExpr.(*ast.TypeAssertExpr); ok {
388
409
  return c.writeTypeAssert(exp.Lhs, typeAssertExpr, exp.Tok)
389
410
  } else if indexExpr, ok := rhsExpr.(*ast.IndexExpr); ok {
@@ -412,6 +433,20 @@ func (c *GoToTSCompiler) WriteStmtAssign(exp *ast.AssignStmt) error {
412
433
  // If none of the specific multi-assign patterns match, fall through to the error check below
413
434
  }
414
435
 
436
+ // Check for single-variable protobuf method calls before general assignment handling
437
+ if len(exp.Lhs) == 1 && len(exp.Rhs) == 1 {
438
+ if callExpr, ok := exp.Rhs[0].(*ast.CallExpr); ok {
439
+ // Handle protobuf UnmarshalVT: err = out.UnmarshalVT(data)
440
+ if c.isProtobufMethodCall(callExpr, "UnmarshalVT") {
441
+ return c.writeProtobufUnmarshalAssignment(exp.Lhs, callExpr, exp.Tok)
442
+ }
443
+ // Handle protobuf UnmarshalJSON: err = out.UnmarshalJSON(data)
444
+ if c.isProtobufMethodCall(callExpr, "UnmarshalJSON") {
445
+ return c.writeProtobufUnmarshalJSONAssignment(exp.Lhs, callExpr, exp.Tok)
446
+ }
447
+ }
448
+ }
449
+
415
450
  // Ensure LHS and RHS have the same length for valid Go code in these cases
416
451
  if len(exp.Lhs) != len(exp.Rhs) {
417
452
  return fmt.Errorf("invalid assignment statement: LHS count (%d) != RHS count (%d)", len(exp.Lhs), len(exp.Rhs))
@@ -4,6 +4,7 @@ import (
4
4
  "fmt"
5
5
  "go/ast"
6
6
  "go/token"
7
+ "go/types"
7
8
  "strings"
8
9
  )
9
10
 
@@ -201,6 +202,92 @@ func (c *GoToTSCompiler) writeTypeAssert(lhs []ast.Expr, typeAssertExpr *ast.Typ
201
202
  c.tsw.WriteLine("")
202
203
  }
203
204
 
205
+ case *ast.IndexExpr:
206
+ // Handle slice[index], ok := expr.(Type) or map[key], ok := expr.(Type)
207
+ // Use unique temporary variable names to avoid redeclaration
208
+ tempValName := fmt.Sprintf("_gs_ta_val_%d_", vLHS.Pos()) // Unique name based on AST position
209
+ tempOkName := fmt.Sprintf("_gs_ta_ok_%d_", vLHS.Pos()) // Unique name based on AST position
210
+
211
+ // Declare temporary variables:
212
+ // let _gs_ta_val_N_: AssertedTypeTS;
213
+ c.tsw.WriteLiterally("let ")
214
+ c.tsw.WriteLiterally(tempValName)
215
+ c.tsw.WriteLiterally(": ")
216
+ c.WriteTypeExpr(assertedType) // TypeScript type for assertedType
217
+ c.tsw.WriteLine("")
218
+
219
+ // let _gs_ta_ok_N_: boolean;
220
+ c.tsw.WriteLiterally("let ")
221
+ c.tsw.WriteLiterally(tempOkName)
222
+ c.tsw.WriteLiterally(": boolean")
223
+ c.tsw.WriteLine("")
224
+
225
+ // Perform type assertion into temporary variables:
226
+ // ({ value: _gs_ta_val_N_, ok: _gs_ta_ok_N_ } = $.typeAssert<AssertedTypeTS>(expr, "GoTypeStr"));
227
+ c.tsw.WriteLiterally("({ value: ")
228
+ c.tsw.WriteLiterally(tempValName)
229
+ c.tsw.WriteLiterally(", ok: ")
230
+ c.tsw.WriteLiterally(tempOkName)
231
+ c.tsw.WriteLiterally(" } = $.typeAssert<")
232
+ c.WriteTypeExpr(assertedType) // Generic: <AssertedTypeTS>
233
+ c.tsw.WriteLiterally(">(")
234
+ if err := c.WriteValueExpr(interfaceExpr); err != nil { // Arg1: interfaceExpr
235
+ return fmt.Errorf("failed to write interface expression in type assertion call: %w", err)
236
+ }
237
+ c.tsw.WriteLiterally(", ")
238
+ c.writeTypeDescription(assertedType) // Arg2: type info for runtime
239
+ c.tsw.WriteLine("))")
240
+
241
+ // Check if this is a map assignment and handle it specially
242
+ if tv, ok := c.pkg.TypesInfo.Types[vLHS.X]; ok {
243
+ if _, isMap := tv.Type.Underlying().(*types.Map); isMap {
244
+ // Map assignment: use $.mapSet(map, key, value)
245
+ c.tsw.WriteLiterally("$.mapSet(")
246
+ if err := c.WriteValueExpr(vLHS.X); err != nil { // Map
247
+ return fmt.Errorf("failed to write map expression in type assertion: %w", err)
248
+ }
249
+ c.tsw.WriteLiterally(", ")
250
+ if err := c.WriteValueExpr(vLHS.Index); err != nil { // Key
251
+ return fmt.Errorf("failed to write map key expression in type assertion: %w", err)
252
+ }
253
+ c.tsw.WriteLiterally(", ")
254
+ c.tsw.WriteLiterally(tempValName) // Value
255
+ c.tsw.WriteLine(")")
256
+ } else {
257
+ // Array/slice assignment: use direct assignment
258
+ // slice[index] = _gs_ta_val_N_;
259
+ if err := c.WriteValueExpr(vLHS.X); err != nil { // Array/slice
260
+ return fmt.Errorf("failed to write array/slice expression in type assertion: %w", err)
261
+ }
262
+ c.tsw.WriteLiterally("![") // Non-null assertion
263
+ if err := c.WriteValueExpr(vLHS.Index); err != nil { // Index
264
+ return fmt.Errorf("failed to write array/slice index expression in type assertion: %w", err)
265
+ }
266
+ c.tsw.WriteLiterally("] = ")
267
+ c.tsw.WriteLiterally(tempValName)
268
+ c.tsw.WriteLine("")
269
+ }
270
+ } else {
271
+ // Fallback: try direct assignment (might fail for maps)
272
+ if err := c.WriteValueExpr(vLHS); err != nil { // Writes indexed expression
273
+ return fmt.Errorf("failed to write LHS indexed expression in type assertion: %w", err)
274
+ }
275
+ c.tsw.WriteLiterally(" = ")
276
+ c.tsw.WriteLiterally(tempValName)
277
+ c.tsw.WriteLine("")
278
+ }
279
+
280
+ // Assign temporary ok to the ok variable (e.g., okName = _gs_ta_ok_N_; or let okName = ...)
281
+ if !okIsBlank {
282
+ if okIsNewInDefine { // okIsNewInDefine was determined earlier based on tok == token.DEFINE and Defs check
283
+ c.tsw.WriteLiterally("let ")
284
+ }
285
+ c.tsw.WriteLiterally(okName)
286
+ c.tsw.WriteLiterally(" = ")
287
+ c.tsw.WriteLiterally(tempOkName)
288
+ c.tsw.WriteLine("")
289
+ }
290
+
204
291
  default:
205
292
  return fmt.Errorf("unhandled LHS expression type for value in type assertion: %T", valueExpr)
206
293
  }
package/compiler/type.go CHANGED
@@ -151,7 +151,10 @@ func (c *GoToTSCompiler) WriteZeroValueForType(typ any) {
151
151
  // Handle named types, especially struct types
152
152
  if _, isStruct := t.Underlying().(*types.Struct); isStruct {
153
153
  // Initialize struct types with a new instance
154
- c.tsw.WriteLiterallyf("new %s()", t.Obj().Name())
154
+ // Use the same logic as WriteNamedType to handle imported types
155
+ c.tsw.WriteLiterally("new ")
156
+ c.WriteNamedType(t)
157
+ c.tsw.WriteLiterally("()")
155
158
  return
156
159
  }
157
160
  // For other named types, use the zero value of the underlying type
@@ -5,5 +5,24 @@ export * from './io.js';
5
5
  export * from './map.js';
6
6
  export * from './slice.js';
7
7
  export * from './type.js';
8
- export declare function copy<T>(dst: T[], src: T[]): number;
8
+ export declare function int(value: number): number;
9
+ export declare function copy<T>(dst: T[] | Uint8Array, src: T[] | Uint8Array | string): number;
9
10
  export declare function multiplyDuration(duration: any, multiplier: number): any;
11
+ /**
12
+ * Normalizes various byte representations into a `Uint8Array` for protobuf compatibility.
13
+ *
14
+ * @param {Uint8Array | number[] | null | undefined | { data: number[] } | { valueOf(): number[] }} bytes
15
+ * The input to normalize. Accepted types:
16
+ * - `Uint8Array`: Returned as-is.
17
+ * - `number[]`: Converted to a `Uint8Array`.
18
+ * - `null` or `undefined`: Returns an empty `Uint8Array`.
19
+ * - `{ data: number[] }`: An object with a `data` property (e.g., `$.Slice<number>`), where `data` is a `number[]`.
20
+ * - `{ valueOf(): number[] }`: An object with a `valueOf` method that returns a `number[]`.
21
+ * @returns {Uint8Array} A normalized `Uint8Array` representation of the input.
22
+ * @throws {Error} If the input type is unsupported or cannot be normalized.
23
+ */
24
+ export declare function normalizeBytes(bytes: Uint8Array | number[] | null | undefined | {
25
+ data: number[];
26
+ } | {
27
+ valueOf(): number[];
28
+ }): Uint8Array;
@@ -5,14 +5,62 @@ export * from './io.js';
5
5
  export * from './map.js';
6
6
  export * from './slice.js';
7
7
  export * from './type.js';
8
+ // int converts a value to a Go int type, handling proper signed integer conversion
9
+ // This ensures that values like 2147483648 (2^31) are properly handled according to Go semantics
10
+ export function int(value) {
11
+ // In Go, int is typically 64-bit on 64-bit systems, but for compatibility with JavaScript
12
+ // we need to handle the conversion properly. The issue is that JavaScript's number type
13
+ // can represent values larger than 32-bit signed integers, but when cast in certain contexts
14
+ // they get interpreted as signed 32-bit integers.
15
+ // For Go's int type on 64-bit systems, we should preserve the full value
16
+ // since JavaScript numbers can safely represent integers up to Number.MAX_SAFE_INTEGER
17
+ return Math.trunc(value);
18
+ }
8
19
  // Copy is the Go builtin function that copies the contents of one slice to another.
9
20
  // It returns the number of elements copied.
10
21
  export function copy(dst, src) {
11
- const n = Math.min(dst.length, src.length);
12
- for (let i = 0; i < n; i++) {
13
- dst[i] = src[i];
22
+ // Handle string to Uint8Array copy (common in Go)
23
+ if (typeof src === 'string' && dst instanceof Uint8Array) {
24
+ const encoder = new TextEncoder();
25
+ const srcBytes = encoder.encode(src);
26
+ const n = Math.min(dst.length, srcBytes.length);
27
+ for (let i = 0; i < n; i++) {
28
+ dst[i] = srcBytes[i];
29
+ }
30
+ return n;
14
31
  }
15
- return n;
32
+ // Handle Uint8Array to Uint8Array copy
33
+ if (dst instanceof Uint8Array && src instanceof Uint8Array) {
34
+ const n = Math.min(dst.length, src.length);
35
+ for (let i = 0; i < n; i++) {
36
+ dst[i] = src[i];
37
+ }
38
+ return n;
39
+ }
40
+ // Handle array to array copy (original implementation)
41
+ if (Array.isArray(dst) && Array.isArray(src)) {
42
+ const n = Math.min(dst.length, src.length);
43
+ for (let i = 0; i < n; i++) {
44
+ dst[i] = src[i];
45
+ }
46
+ return n;
47
+ }
48
+ // Handle mixed types - convert to compatible format
49
+ if (dst instanceof Uint8Array && Array.isArray(src)) {
50
+ const n = Math.min(dst.length, src.length);
51
+ for (let i = 0; i < n; i++) {
52
+ dst[i] = src[i];
53
+ }
54
+ return n;
55
+ }
56
+ if (Array.isArray(dst) && src instanceof Uint8Array) {
57
+ const n = Math.min(dst.length, src.length);
58
+ for (let i = 0; i < n; i++) {
59
+ dst[i] = src[i];
60
+ }
61
+ return n;
62
+ }
63
+ throw new Error(`Unsupported copy operation between ${typeof dst} and ${typeof src}`);
16
64
  }
17
65
  // Duration multiplication helper for time package operations
18
66
  // Handles expressions like time.Hour * 24
@@ -43,4 +91,47 @@ export function multiplyDuration(duration, multiplier) {
43
91
  }
44
92
  throw new Error(`Cannot multiply duration of type ${typeof duration}`);
45
93
  }
94
+ /**
95
+ * Normalizes various byte representations into a `Uint8Array` for protobuf compatibility.
96
+ *
97
+ * @param {Uint8Array | number[] | null | undefined | { data: number[] } | { valueOf(): number[] }} bytes
98
+ * The input to normalize. Accepted types:
99
+ * - `Uint8Array`: Returned as-is.
100
+ * - `number[]`: Converted to a `Uint8Array`.
101
+ * - `null` or `undefined`: Returns an empty `Uint8Array`.
102
+ * - `{ data: number[] }`: An object with a `data` property (e.g., `$.Slice<number>`), where `data` is a `number[]`.
103
+ * - `{ valueOf(): number[] }`: An object with a `valueOf` method that returns a `number[]`.
104
+ * @returns {Uint8Array} A normalized `Uint8Array` representation of the input.
105
+ * @throws {Error} If the input type is unsupported or cannot be normalized.
106
+ */
107
+ export function normalizeBytes(bytes) {
108
+ if (bytes === null || bytes === undefined) {
109
+ return new Uint8Array(0);
110
+ }
111
+ if (bytes instanceof Uint8Array) {
112
+ return bytes;
113
+ }
114
+ // Handle $.Slice<number> (which has a .data property that's a number[])
115
+ if (bytes &&
116
+ typeof bytes === 'object' &&
117
+ 'data' in bytes &&
118
+ Array.isArray(bytes.data)) {
119
+ return new Uint8Array(bytes.data);
120
+ }
121
+ // Handle plain number arrays
122
+ if (Array.isArray(bytes)) {
123
+ return new Uint8Array(bytes);
124
+ }
125
+ // Handle objects with valueOf() method that returns a number array
126
+ if (bytes &&
127
+ typeof bytes === 'object' &&
128
+ 'valueOf' in bytes &&
129
+ typeof bytes.valueOf === 'function') {
130
+ const value = bytes.valueOf();
131
+ if (Array.isArray(value)) {
132
+ return new Uint8Array(value);
133
+ }
134
+ }
135
+ throw new Error(`Cannot normalize bytes of type ${typeof bytes}: ${bytes}`);
136
+ }
46
137
  //# sourceMappingURL=builtin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"builtin.js","sourceRoot":"","sources":["../../../gs/builtin/builtin.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AAEzB,oFAAoF;AACpF,4CAA4C;AAC5C,MAAM,UAAU,IAAI,CAAI,GAAQ,EAAE,GAAQ;IACxC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IACD,OAAO,CAAC,CAAA;AACV,CAAC;AAED,6DAA6D;AAC7D,0CAA0C;AAC1C,MAAM,UAAU,gBAAgB,CAAC,QAAa,EAAE,UAAkB;IAChE,oEAAoE;IACpE,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;QACxD,OAAO,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;IACtC,CAAC;IAED,gEAAgE;IAChE,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QACvD,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAA;QACnC,gEAAgE;QAChE,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,gDAAgD;YAChD,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;gBACzB,OAAO,IAAI,QAAQ,CAAC,WAAW,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAA;YACxD,CAAC;YACD,gDAAgD;YAChD,OAAO;gBACL,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,GAAG,UAAU;gBACpC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAC,QAAQ,EAAE,GAAG,IAAI;aAC1D,CAAA;QACH,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,QAAQ,GAAG,UAAU,CAAA;IAC9B,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,oCAAoC,OAAO,QAAQ,EAAE,CAAC,CAAA;AACxE,CAAC"}
1
+ {"version":3,"file":"builtin.js","sourceRoot":"","sources":["../../../gs/builtin/builtin.ts"],"names":[],"mappings":"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"}
@@ -137,7 +137,7 @@ export declare const sliceString: (str: string, low?: number, high?: number) =>
137
137
  * @param bytes The Slice<number> to convert.
138
138
  * @returns The resulting string.
139
139
  */
140
- export declare const bytesToString: (bytes: Slice<number> | Uint8Array) => string;
140
+ export declare const bytesToString: (bytes: Slice<number> | Uint8Array | string) => string;
141
141
  /**
142
142
  * Converts a string to a Uint8Array (byte slice).
143
143
  * @param s The input string.
@@ -1,6 +1,22 @@
1
- // asArray type-asserts a slice to an array type.
1
+ // asArray converts a slice to a JavaScript array.
2
2
  export function asArray(slice) {
3
- return slice;
3
+ if (slice === null || slice === undefined) {
4
+ return [];
5
+ }
6
+ if (slice instanceof Uint8Array) {
7
+ return Array.from(slice);
8
+ }
9
+ if (isComplexSlice(slice)) {
10
+ const result = [];
11
+ for (let i = 0; i < slice.__meta__.length; i++) {
12
+ result.push(slice.__meta__.backing[slice.__meta__.offset + i]);
13
+ }
14
+ return result;
15
+ }
16
+ if (Array.isArray(slice)) {
17
+ return slice;
18
+ }
19
+ return [];
4
20
  }
5
21
  /**
6
22
  * isComplexSlice checks if a slice is a complex slice (has __meta__ property)
@@ -736,6 +752,9 @@ export const sliceString = (str, low, high) => {
736
752
  export const bytesToString = (bytes) => {
737
753
  if (bytes === null)
738
754
  return '';
755
+ // If it's already a string, just return it
756
+ if (typeof bytes === 'string')
757
+ return bytes;
739
758
  if (bytes instanceof Uint8Array) {
740
759
  return new TextDecoder().decode(bytes);
741
760
  }