goscript 0.0.84 → 0.1.1

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 (428) hide show
  1. package/README.md +267 -243
  2. package/cmd/goscript/cmd-test.go +193 -0
  3. package/cmd/goscript/cmd-test_test.go +76 -0
  4. package/cmd/goscript/cmd_compile.go +70 -69
  5. package/cmd/goscript/cmd_compile_test.go +79 -0
  6. package/cmd/goscript/main.go +11 -5
  7. package/compiler/build-flags.go +38 -0
  8. package/compiler/compile-request.go +220 -0
  9. package/compiler/compiler.go +16 -1336
  10. package/compiler/compliance_test.go +188 -0
  11. package/compiler/config.go +6 -13
  12. package/compiler/diagnostic.go +70 -0
  13. package/compiler/gotest/owner.go +24 -0
  14. package/compiler/gotest/package-result.go +67 -0
  15. package/compiler/gotest/request.go +145 -0
  16. package/compiler/gotest/result.go +28 -0
  17. package/compiler/gotest/runner.go +588 -0
  18. package/compiler/gotest/runner_test.go +627 -0
  19. package/compiler/gotest/test.go +9 -0
  20. package/compiler/index.test.ts +28 -28
  21. package/compiler/index.ts +40 -72
  22. package/compiler/lowered-program.go +184 -0
  23. package/compiler/lowering.go +8072 -0
  24. package/compiler/override-facts.go +307 -0
  25. package/compiler/override-registry.go +283 -0
  26. package/compiler/override-registry_test.go +254 -0
  27. package/compiler/package-graph.go +254 -0
  28. package/compiler/package-graph_test.go +316 -0
  29. package/compiler/package-test-function.go +9 -0
  30. package/compiler/package-test-graph-package.go +40 -0
  31. package/compiler/package-test-graph-variant.go +105 -0
  32. package/compiler/package-test-graph.go +117 -0
  33. package/compiler/package-test-graph_test.go +144 -0
  34. package/compiler/result.go +13 -0
  35. package/compiler/runtime-contract.go +439 -0
  36. package/compiler/runtime-contract_test.go +104 -0
  37. package/compiler/semantic-model-types.go +113 -0
  38. package/compiler/semantic-model.go +1422 -0
  39. package/compiler/semantic-model_test.go +471 -0
  40. package/compiler/service.go +133 -0
  41. package/compiler/skeleton_test.go +1775 -0
  42. package/compiler/tsworkspace/owner.go +334 -0
  43. package/compiler/tsworkspace/owner_test.go +93 -0
  44. package/compiler/tsworkspace/result.go +17 -0
  45. package/compiler/typescript-emitter.go +1040 -0
  46. package/compiler/wasm/compile.go +2 -3
  47. package/compiler/wasm/compile_test.go +79 -0
  48. package/compiler/wasm_api.go +140 -124
  49. package/dist/compiler/index.d.ts +1 -3
  50. package/dist/compiler/index.js +31 -55
  51. package/dist/compiler/index.js.map +1 -1
  52. package/dist/gs/builtin/builtin.d.ts +33 -2
  53. package/dist/gs/builtin/builtin.js +217 -6
  54. package/dist/gs/builtin/builtin.js.map +1 -1
  55. package/dist/gs/builtin/channel.d.ts +11 -3
  56. package/dist/gs/builtin/channel.js +12 -0
  57. package/dist/gs/builtin/channel.js.map +1 -1
  58. package/dist/gs/builtin/hostio.d.ts +15 -1
  59. package/dist/gs/builtin/hostio.js +134 -49
  60. package/dist/gs/builtin/hostio.js.map +1 -1
  61. package/dist/gs/builtin/index.d.ts +1 -0
  62. package/dist/gs/builtin/index.js +1 -0
  63. package/dist/gs/builtin/index.js.map +1 -1
  64. package/dist/gs/builtin/slice.d.ts +23 -3
  65. package/dist/gs/builtin/slice.js +216 -44
  66. package/dist/gs/builtin/slice.js.map +1 -1
  67. package/dist/gs/builtin/type.d.ts +16 -2
  68. package/dist/gs/builtin/type.js +134 -21
  69. package/dist/gs/builtin/type.js.map +1 -1
  70. package/dist/gs/builtin/varRef.d.ts +5 -0
  71. package/dist/gs/builtin/varRef.js +23 -0
  72. package/dist/gs/builtin/varRef.js.map +1 -1
  73. package/dist/gs/bytes/buffer.gs.js +48 -44
  74. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  75. package/dist/gs/bytes/bytes.gs.js.map +1 -1
  76. package/dist/gs/bytes/reader.gs.js +20 -18
  77. package/dist/gs/bytes/reader.gs.js.map +1 -1
  78. package/dist/gs/context/context.d.ts +5 -4
  79. package/dist/gs/context/context.js +10 -10
  80. package/dist/gs/context/context.js.map +1 -1
  81. package/dist/gs/crypto/internal/fips140deps/byteorder/index.d.ts +1 -0
  82. package/dist/gs/crypto/internal/fips140deps/byteorder/index.js +2 -0
  83. package/dist/gs/crypto/internal/fips140deps/byteorder/index.js.map +1 -0
  84. package/dist/gs/crypto/internal/fips140deps/godebug/index.d.ts +1 -0
  85. package/dist/gs/crypto/internal/fips140deps/godebug/index.js +2 -0
  86. package/dist/gs/crypto/internal/fips140deps/godebug/index.js.map +1 -0
  87. package/dist/gs/crypto/rand/index.d.ts +5 -0
  88. package/dist/gs/crypto/rand/index.js +77 -0
  89. package/dist/gs/crypto/rand/index.js.map +1 -0
  90. package/dist/gs/embed/index.d.ts +7 -0
  91. package/dist/gs/embed/index.js +16 -0
  92. package/dist/gs/embed/index.js.map +1 -0
  93. package/dist/gs/encoding/json/index.d.ts +4 -0
  94. package/dist/gs/encoding/json/index.js +178 -0
  95. package/dist/gs/encoding/json/index.js.map +1 -0
  96. package/dist/gs/errors/errors.d.ts +4 -0
  97. package/dist/gs/errors/errors.js +81 -0
  98. package/dist/gs/errors/errors.js.map +1 -1
  99. package/dist/gs/fmt/fmt.d.ts +4 -4
  100. package/dist/gs/fmt/fmt.js +42 -11
  101. package/dist/gs/fmt/fmt.js.map +1 -1
  102. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +36 -1
  103. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +212 -2
  104. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  105. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +189 -0
  106. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +825 -0
  107. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -0
  108. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +163 -0
  109. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +449 -0
  110. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -0
  111. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
  112. package/dist/gs/github.com/klauspost/compress/internal/le/index.d.ts +9 -0
  113. package/dist/gs/github.com/klauspost/compress/internal/le/index.js +71 -0
  114. package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -0
  115. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  116. package/dist/gs/github.com/pkg/errors/stack.js.map +1 -1
  117. package/dist/gs/go/internal/scannerhooks/index.d.ts +3 -0
  118. package/dist/gs/go/internal/scannerhooks/index.js +5 -0
  119. package/dist/gs/go/internal/scannerhooks/index.js.map +1 -0
  120. package/dist/gs/go/scanner/index.d.ts +42 -0
  121. package/dist/gs/go/scanner/index.js +155 -0
  122. package/dist/gs/go/scanner/index.js.map +1 -0
  123. package/dist/gs/go/token/index.d.ts +187 -0
  124. package/dist/gs/go/token/index.js +578 -0
  125. package/dist/gs/go/token/index.js.map +1 -0
  126. package/dist/gs/internal/abi/index.d.ts +4 -0
  127. package/dist/gs/internal/abi/index.js +10 -0
  128. package/dist/gs/internal/abi/index.js.map +1 -1
  129. package/dist/gs/internal/bytealg/index.d.ts +2 -0
  130. package/dist/gs/internal/bytealg/index.js +14 -0
  131. package/dist/gs/internal/bytealg/index.js.map +1 -1
  132. package/dist/gs/internal/byteorder/index.d.ts +8 -2
  133. package/dist/gs/internal/byteorder/index.js +56 -25
  134. package/dist/gs/internal/byteorder/index.js.map +1 -1
  135. package/dist/gs/internal/godebug/index.d.ts +12 -0
  136. package/dist/gs/internal/godebug/index.js +30 -0
  137. package/dist/gs/internal/godebug/index.js.map +1 -0
  138. package/dist/gs/io/fs/fs.js.map +1 -1
  139. package/dist/gs/io/fs/index.d.ts +1 -0
  140. package/dist/gs/io/fs/index.js +1 -0
  141. package/dist/gs/io/fs/index.js.map +1 -1
  142. package/dist/gs/io/fs/readdir.js.map +1 -1
  143. package/dist/gs/io/fs/readfile.js.map +1 -1
  144. package/dist/gs/io/fs/readlink.d.ts +8 -0
  145. package/dist/gs/io/fs/readlink.js +64 -0
  146. package/dist/gs/io/fs/readlink.js.map +1 -0
  147. package/dist/gs/io/fs/stat.js.map +1 -1
  148. package/dist/gs/io/fs/sub.js.map +1 -1
  149. package/dist/gs/io/fs/walk.d.ts +3 -3
  150. package/dist/gs/io/fs/walk.js +7 -7
  151. package/dist/gs/io/fs/walk.js.map +1 -1
  152. package/dist/gs/io/io.d.ts +40 -6
  153. package/dist/gs/io/io.js +151 -26
  154. package/dist/gs/io/io.js.map +1 -1
  155. package/dist/gs/maps/iter.d.ts +3 -3
  156. package/dist/gs/maps/iter.js +3 -3
  157. package/dist/gs/maps/iter.js.map +1 -1
  158. package/dist/gs/maps/maps.d.ts +2 -2
  159. package/dist/gs/maps/maps.js +1 -1
  160. package/dist/gs/maps/maps.js.map +1 -1
  161. package/dist/gs/math/bits/index.d.ts +13 -4
  162. package/dist/gs/math/bits/index.js +66 -34
  163. package/dist/gs/math/bits/index.js.map +1 -1
  164. package/dist/gs/math/const.gs.d.ts +5 -5
  165. package/dist/gs/math/const.gs.js +4 -4
  166. package/dist/gs/math/const.gs.js.map +1 -1
  167. package/dist/gs/mime/index.d.ts +1 -0
  168. package/dist/gs/mime/index.js +50 -0
  169. package/dist/gs/mime/index.js.map +1 -0
  170. package/dist/gs/net/http/httptest/index.d.ts +11 -0
  171. package/dist/gs/net/http/httptest/index.js +21 -0
  172. package/dist/gs/net/http/httptest/index.js.map +1 -0
  173. package/dist/gs/net/http/index.d.ts +27 -0
  174. package/dist/gs/net/http/index.js +61 -0
  175. package/dist/gs/net/http/index.js.map +1 -0
  176. package/dist/gs/os/dir_unix.gs.js +2 -2
  177. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  178. package/dist/gs/os/error.gs.js +2 -4
  179. package/dist/gs/os/error.gs.js.map +1 -1
  180. package/dist/gs/os/exec.gs.js.map +1 -1
  181. package/dist/gs/os/exec_posix.gs.js.map +1 -1
  182. package/dist/gs/os/rawconn_js.gs.js.map +1 -1
  183. package/dist/gs/os/root_js.gs.js.map +1 -1
  184. package/dist/gs/os/tempfile.gs.js +66 -9
  185. package/dist/gs/os/tempfile.gs.js.map +1 -1
  186. package/dist/gs/os/types.gs.js.map +1 -1
  187. package/dist/gs/os/types_js.gs.js +9 -9
  188. package/dist/gs/os/types_js.gs.js.map +1 -1
  189. package/dist/gs/os/types_unix.gs.js.map +1 -1
  190. package/dist/gs/path/filepath/match.js +165 -3
  191. package/dist/gs/path/filepath/match.js.map +1 -1
  192. package/dist/gs/path/filepath/path.d.ts +3 -1
  193. package/dist/gs/path/filepath/path.js +133 -4
  194. package/dist/gs/path/filepath/path.js.map +1 -1
  195. package/dist/gs/path/match.js.map +1 -1
  196. package/dist/gs/path/path.d.ts +4 -1
  197. package/dist/gs/path/path.js +16 -4
  198. package/dist/gs/path/path.js.map +1 -1
  199. package/dist/gs/reflect/index.d.ts +3 -3
  200. package/dist/gs/reflect/index.js +2 -2
  201. package/dist/gs/reflect/index.js.map +1 -1
  202. package/dist/gs/reflect/map.js +3 -0
  203. package/dist/gs/reflect/map.js.map +1 -1
  204. package/dist/gs/reflect/type.d.ts +9 -5
  205. package/dist/gs/reflect/type.js +233 -21
  206. package/dist/gs/reflect/type.js.map +1 -1
  207. package/dist/gs/reflect/types.js.map +1 -1
  208. package/dist/gs/reflect/visiblefields.js.map +1 -1
  209. package/dist/gs/runtime/debug/index.d.ts +2 -0
  210. package/dist/gs/runtime/debug/index.js +8 -0
  211. package/dist/gs/runtime/debug/index.js.map +1 -0
  212. package/dist/gs/runtime/runtime.d.ts +35 -3
  213. package/dist/gs/runtime/runtime.js +72 -0
  214. package/dist/gs/runtime/runtime.js.map +1 -1
  215. package/dist/gs/slices/slices.d.ts +24 -5
  216. package/dist/gs/slices/slices.js +214 -5
  217. package/dist/gs/slices/slices.js.map +1 -1
  218. package/dist/gs/sort/slice.gs.d.ts +3 -3
  219. package/dist/gs/sort/slice.gs.js +6 -6
  220. package/dist/gs/sort/slice.gs.js.map +1 -1
  221. package/dist/gs/sort/sort.gs.d.ts +4 -4
  222. package/dist/gs/sort/sort.gs.js +11 -8
  223. package/dist/gs/sort/sort.gs.js.map +1 -1
  224. package/dist/gs/strconv/atoi.gs.js.map +1 -1
  225. package/dist/gs/strconv/quote.gs.js.map +1 -1
  226. package/dist/gs/strings/builder.d.ts +1 -1
  227. package/dist/gs/strings/builder.js +3 -2
  228. package/dist/gs/strings/builder.js.map +1 -1
  229. package/dist/gs/strings/reader.js.map +1 -1
  230. package/dist/gs/strings/replace.js.map +1 -1
  231. package/dist/gs/sync/atomic/type.gs.d.ts +9 -8
  232. package/dist/gs/sync/atomic/type.gs.js +0 -2
  233. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  234. package/dist/gs/sync/atomic/value.gs.js.map +1 -1
  235. package/dist/gs/sync/sync.d.ts +3 -0
  236. package/dist/gs/sync/sync.js +39 -0
  237. package/dist/gs/sync/sync.js.map +1 -1
  238. package/dist/gs/syscall/constants.d.ts +36 -24
  239. package/dist/gs/syscall/constants.js +12 -0
  240. package/dist/gs/syscall/constants.js.map +1 -1
  241. package/dist/gs/syscall/errors.d.ts +2 -0
  242. package/dist/gs/syscall/errors.js +8 -0
  243. package/dist/gs/syscall/errors.js.map +1 -1
  244. package/dist/gs/syscall/fs.d.ts +43 -0
  245. package/dist/gs/syscall/fs.js +102 -0
  246. package/dist/gs/syscall/fs.js.map +1 -1
  247. package/dist/gs/syscall/js/index.d.ts +90 -0
  248. package/dist/gs/syscall/js/index.js +375 -0
  249. package/dist/gs/syscall/js/index.js.map +1 -0
  250. package/dist/gs/syscall/types.d.ts +22 -0
  251. package/dist/gs/syscall/types.js +45 -1
  252. package/dist/gs/syscall/types.js.map +1 -1
  253. package/dist/gs/testing/index.d.ts +1 -0
  254. package/dist/gs/testing/index.js +2 -0
  255. package/dist/gs/testing/index.js.map +1 -0
  256. package/dist/gs/testing/testing.d.ts +77 -0
  257. package/dist/gs/testing/testing.js +301 -0
  258. package/dist/gs/testing/testing.js.map +1 -0
  259. package/dist/gs/time/time.d.ts +41 -4
  260. package/dist/gs/time/time.js +205 -36
  261. package/dist/gs/time/time.js.map +1 -1
  262. package/dist/gs/unicode/unicode.d.ts +23 -1
  263. package/dist/gs/unicode/unicode.js +79 -10
  264. package/dist/gs/unicode/unicode.js.map +1 -1
  265. package/dist/gs/unicode/utf8/utf8.d.ts +4 -4
  266. package/dist/gs/unicode/utf8/utf8.js +24 -11
  267. package/dist/gs/unicode/utf8/utf8.js.map +1 -1
  268. package/dist/gs/unique/index.d.ts +11 -0
  269. package/dist/gs/unique/index.js +71 -0
  270. package/dist/gs/unique/index.js.map +1 -0
  271. package/go.mod +2 -2
  272. package/go.sum +9 -0
  273. package/gs/builtin/builtin.ts +266 -8
  274. package/gs/builtin/channel.ts +22 -0
  275. package/gs/builtin/hostio.test.ts +177 -0
  276. package/gs/builtin/hostio.ts +171 -56
  277. package/gs/builtin/index.ts +1 -0
  278. package/gs/builtin/runtime-contract.test.ts +356 -0
  279. package/gs/builtin/slice.ts +259 -50
  280. package/gs/builtin/type.ts +188 -30
  281. package/gs/builtin/varRef.ts +38 -1
  282. package/gs/bytes/buffer.gs.ts +48 -44
  283. package/gs/bytes/meta.json +8 -3
  284. package/gs/bytes/reader.gs.ts +20 -19
  285. package/gs/context/context.test.ts +41 -0
  286. package/gs/context/context.ts +22 -26
  287. package/gs/crypto/internal/fips140deps/byteorder/index.ts +1 -0
  288. package/gs/crypto/internal/fips140deps/godebug/index.ts +1 -0
  289. package/gs/crypto/rand/index.test.ts +32 -0
  290. package/gs/crypto/rand/index.ts +90 -0
  291. package/gs/crypto/rand/meta.json +5 -0
  292. package/gs/embed/index.ts +20 -0
  293. package/gs/embed/meta.json +5 -0
  294. package/gs/encoding/json/index.test.ts +79 -0
  295. package/gs/encoding/json/index.ts +210 -0
  296. package/gs/errors/errors.test.ts +82 -0
  297. package/gs/errors/errors.ts +104 -0
  298. package/gs/fmt/fmt.ts +56 -16
  299. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +95 -0
  300. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +300 -2
  301. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +159 -0
  302. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +1005 -0
  303. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +719 -0
  304. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +40 -0
  305. package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/meta.json +3 -1
  306. package/gs/github.com/klauspost/compress/internal/le/index.test.ts +36 -0
  307. package/gs/github.com/klauspost/compress/internal/le/index.ts +114 -0
  308. package/gs/go/internal/scannerhooks/index.test.ts +14 -0
  309. package/gs/go/internal/scannerhooks/index.ts +9 -0
  310. package/gs/go/scanner/index.test.ts +72 -0
  311. package/gs/go/scanner/index.ts +204 -0
  312. package/gs/go/token/index.test.ts +67 -0
  313. package/gs/go/token/index.ts +686 -0
  314. package/gs/internal/abi/index.test.ts +18 -0
  315. package/gs/internal/abi/index.ts +14 -0
  316. package/gs/internal/bytealg/index.test.ts +18 -0
  317. package/gs/internal/bytealg/index.ts +16 -0
  318. package/gs/internal/byteorder/index.test.ts +39 -0
  319. package/gs/internal/byteorder/index.ts +100 -27
  320. package/gs/internal/godebug/index.test.ts +16 -0
  321. package/gs/internal/godebug/index.ts +35 -0
  322. package/gs/io/fs/index.ts +1 -0
  323. package/gs/io/fs/meta.json +5 -0
  324. package/gs/io/fs/readlink.test.ts +43 -0
  325. package/gs/io/fs/readlink.ts +77 -0
  326. package/gs/io/fs/walk.test.ts +61 -0
  327. package/gs/io/fs/walk.ts +9 -9
  328. package/gs/io/io.ts +174 -31
  329. package/gs/io/meta.json +10 -2
  330. package/gs/maps/iter.ts +12 -6
  331. package/gs/maps/maps.ts +8 -6
  332. package/gs/math/bits/index.ts +103 -47
  333. package/gs/math/const.gs.test.ts +11 -5
  334. package/gs/math/const.gs.ts +5 -6
  335. package/gs/mime/index.ts +54 -0
  336. package/gs/net/http/httptest/index.ts +25 -0
  337. package/gs/net/http/index.test.ts +20 -0
  338. package/gs/net/http/index.ts +81 -0
  339. package/gs/os/dir_unix.gs.ts +2 -3
  340. package/gs/os/file_unix_js.test.ts +50 -0
  341. package/gs/os/meta.json +1 -2
  342. package/gs/os/tempfile.gs.test.ts +85 -0
  343. package/gs/os/tempfile.gs.ts +71 -11
  344. package/gs/os/types_js.gs.ts +11 -11
  345. package/gs/path/filepath/match.test.ts +31 -12
  346. package/gs/path/filepath/match.ts +178 -3
  347. package/gs/path/filepath/path.test.ts +25 -0
  348. package/gs/path/filepath/path.ts +159 -5
  349. package/gs/path/path.ts +20 -5
  350. package/gs/reflect/index.ts +2 -1
  351. package/gs/reflect/map.test.ts +19 -0
  352. package/gs/reflect/map.ts +4 -0
  353. package/gs/reflect/type.ts +298 -29
  354. package/gs/reflect/typefor.test.ts +75 -0
  355. package/gs/runtime/debug/index.test.ts +24 -0
  356. package/gs/runtime/debug/index.ts +8 -0
  357. package/gs/runtime/runtime.test.ts +19 -0
  358. package/gs/runtime/runtime.ts +98 -3
  359. package/gs/slices/slices.test.ts +94 -0
  360. package/gs/slices/slices.ts +245 -5
  361. package/gs/sort/meta.json +7 -0
  362. package/gs/sort/slice.gs.ts +16 -7
  363. package/gs/sort/sort.gs.ts +16 -13
  364. package/gs/strings/builder.ts +4 -3
  365. package/gs/sync/atomic/type.gs.ts +13 -14
  366. package/gs/sync/meta.json +3 -1
  367. package/gs/sync/sync.test.ts +36 -0
  368. package/gs/sync/sync.ts +39 -0
  369. package/gs/syscall/constants.ts +39 -24
  370. package/gs/syscall/errors.ts +10 -0
  371. package/gs/syscall/fs.ts +195 -0
  372. package/gs/syscall/js/index.ts +458 -0
  373. package/gs/syscall/js/meta.json +4 -0
  374. package/gs/syscall/net.test.ts +85 -0
  375. package/gs/syscall/types.ts +56 -0
  376. package/gs/testing/index.ts +1 -0
  377. package/gs/testing/meta.json +5 -0
  378. package/gs/testing/testing.test.ts +90 -0
  379. package/gs/testing/testing.ts +382 -0
  380. package/gs/time/time.test.ts +106 -0
  381. package/gs/time/time.ts +278 -57
  382. package/gs/unicode/unicode.test.ts +25 -0
  383. package/gs/unicode/unicode.ts +119 -9
  384. package/gs/unicode/utf8/utf8.test.ts +13 -0
  385. package/gs/unicode/utf8/utf8.ts +28 -16
  386. package/gs/unique/index.ts +91 -0
  387. package/package.json +14 -13
  388. package/compiler/analysis.go +0 -3475
  389. package/compiler/analysis_test.go +0 -338
  390. package/compiler/assignment.go +0 -580
  391. package/compiler/builtin_test.go +0 -92
  392. package/compiler/code-writer.go +0 -115
  393. package/compiler/compiler_test.go +0 -149
  394. package/compiler/composite-lit.go +0 -779
  395. package/compiler/config_test.go +0 -62
  396. package/compiler/constraint.go +0 -86
  397. package/compiler/decl.go +0 -801
  398. package/compiler/expr-call-async.go +0 -188
  399. package/compiler/expr-call-builtins.go +0 -208
  400. package/compiler/expr-call-helpers.go +0 -382
  401. package/compiler/expr-call-make.go +0 -318
  402. package/compiler/expr-call-type-conversion.go +0 -520
  403. package/compiler/expr-call.go +0 -413
  404. package/compiler/expr-selector.go +0 -343
  405. package/compiler/expr-star.go +0 -82
  406. package/compiler/expr-type.go +0 -442
  407. package/compiler/expr-value.go +0 -89
  408. package/compiler/expr.go +0 -773
  409. package/compiler/field.go +0 -183
  410. package/compiler/gs_dependencies_test.go +0 -298
  411. package/compiler/lit.go +0 -322
  412. package/compiler/output.go +0 -72
  413. package/compiler/primitive.go +0 -149
  414. package/compiler/protobuf.go +0 -697
  415. package/compiler/sanitize.go +0 -100
  416. package/compiler/spec-struct.go +0 -995
  417. package/compiler/spec-value.go +0 -540
  418. package/compiler/spec.go +0 -725
  419. package/compiler/stmt-assign.go +0 -664
  420. package/compiler/stmt-for.go +0 -266
  421. package/compiler/stmt-range.go +0 -475
  422. package/compiler/stmt-select.go +0 -262
  423. package/compiler/stmt-type-switch.go +0 -147
  424. package/compiler/stmt.go +0 -1308
  425. package/compiler/type-assert.go +0 -386
  426. package/compiler/type-info.go +0 -156
  427. package/compiler/type-utils.go +0 -207
  428. package/compiler/type.go +0 -892
@@ -1,17 +1,18 @@
1
1
  import * as $ from '@goscript/builtin/index.js'
2
+ import * as time from '@goscript/time/index.js'
2
3
 
3
4
  export const Canceled = $.newError('context canceled')
4
5
 
5
6
  export const DeadlineExceeded = $.newError('context deadline exceeded')
6
7
 
7
8
  // Function types
8
- export type CancelFunc = () => void
9
+ export type CancelFunc = (() => void) | null
9
10
  export type CancelCauseFunc = (cause: $.GoError) => void
10
11
 
11
12
  // Context interface matching Go's context.Context
12
13
  export type Context = null | {
13
14
  // Deadline returns the time when work done on behalf of this context should be canceled
14
- Deadline(): [Date | null, boolean]
15
+ Deadline(): [time.Time, boolean]
15
16
 
16
17
  // Done returns a channel that's closed when work done on behalf of this context should be canceled
17
18
  Done(): $.Channel<{}>
@@ -28,7 +29,7 @@ export type ContextNonNil = Exclude<Context, null>
28
29
 
29
30
  // Base implementation for all contexts
30
31
  abstract class baseContext implements ContextNonNil {
31
- abstract Deadline(): [Date | null, boolean]
32
+ abstract Deadline(): [time.Time, boolean]
32
33
  abstract Done(): $.Channel<{}>
33
34
  abstract Err(): $.GoError
34
35
  abstract Value(key: any): any
@@ -42,8 +43,8 @@ class backgroundContext extends baseContext {
42
43
  return backgroundContext.neverClosedChannel
43
44
  }
44
45
 
45
- Deadline(): [Date | null, boolean] {
46
- return [null, false]
46
+ Deadline(): [time.Time, boolean] {
47
+ return [new time.Time(), false]
47
48
  }
48
49
 
49
50
  Done(): $.Channel<{}> {
@@ -73,7 +74,7 @@ class valueContext extends baseContext {
73
74
  return this.parent
74
75
  }
75
76
 
76
- Deadline(): [Date | null, boolean] {
77
+ Deadline(): [time.Time, boolean] {
77
78
  return this.parent.Deadline()
78
79
  }
79
80
 
@@ -109,7 +110,7 @@ class cancelContext extends baseContext {
109
110
  this.doneChannel = $.makeChannel<{}>(0, {}, 'both')
110
111
  }
111
112
 
112
- Deadline(): [Date | null, boolean] {
113
+ Deadline(): [time.Time, boolean] {
113
114
  return this.parent.Deadline()
114
115
  }
115
116
 
@@ -195,21 +196,20 @@ class cancelContext extends baseContext {
195
196
 
196
197
  // Timer context with deadline
197
198
  class timerContext extends cancelContext {
198
- private deadline: Date
199
+ private deadline: time.Time
199
200
  private timer: any
200
201
 
201
- constructor(parent: ContextNonNil, deadline: Date) {
202
+ constructor(parent: ContextNonNil, deadline: time.Time) {
202
203
  super(parent)
203
- this.deadline = deadline
204
+ this.deadline = deadline.clone()
204
205
  }
205
206
 
206
- Deadline(): [Date | null, boolean] {
207
- return [this.deadline, true]
207
+ Deadline(): [time.Time, boolean] {
208
+ return [this.deadline.clone(), true]
208
209
  }
209
210
 
210
211
  startTimer(): void {
211
- const now = Date.now()
212
- const duration = this.deadline.getTime() - now
212
+ const duration = this.deadline.Sub(time.Now()) / 1000000
213
213
 
214
214
  if (duration <= 0) {
215
215
  // Already expired
@@ -237,8 +237,8 @@ class withoutCancelContext extends baseContext {
237
237
  super()
238
238
  }
239
239
 
240
- Deadline(): [Date | null, boolean] {
241
- return [null, false]
240
+ Deadline(): [time.Time, boolean] {
241
+ return [new time.Time(), false]
242
242
  }
243
243
 
244
244
  Done(): $.Channel<{}> {
@@ -305,7 +305,7 @@ export function WithCancelCause(
305
305
  // WithDeadline returns a copy of parent with the deadline adjusted to be no later than d
306
306
  export function WithDeadline(
307
307
  parent: Context,
308
- d: Date,
308
+ d: time.Time,
309
309
  ): [ContextNonNil, CancelFunc] {
310
310
  return WithDeadlineCause(parent, d, null)
311
311
  }
@@ -313,7 +313,7 @@ export function WithDeadline(
313
313
  // WithDeadlineCause is like WithDeadline but also sets the cause
314
314
  export function WithDeadlineCause(
315
315
  parent: Context,
316
- d: Date,
316
+ d: time.Time,
317
317
  cause: $.GoError,
318
318
  ): [ContextNonNil, CancelFunc] {
319
319
  if (parent === null) {
@@ -321,7 +321,7 @@ export function WithDeadlineCause(
321
321
  }
322
322
  // Check if parent deadline is already earlier
323
323
  const [parentDeadline, ok] = parent.Deadline()
324
- if (ok && parentDeadline && parentDeadline <= d) {
324
+ if (ok && (parentDeadline.Before(d) || parentDeadline.Equal(d))) {
325
325
  // Parent deadline is already sooner
326
326
  return WithCancel(parent)
327
327
  }
@@ -343,7 +343,7 @@ export function WithTimeout(
343
343
  parent: Context,
344
344
  timeout: number,
345
345
  ): [ContextNonNil, CancelFunc] {
346
- return WithDeadline(parent, new Date(Date.now() + timeout / 1000000))
346
+ return WithDeadline(parent, time.Now().Add(timeout))
347
347
  }
348
348
 
349
349
  // WithTimeoutCause is like WithTimeout but also sets the cause
@@ -352,11 +352,7 @@ export function WithTimeoutCause(
352
352
  timeout: number,
353
353
  cause: $.GoError,
354
354
  ): [ContextNonNil, CancelFunc] {
355
- return WithDeadlineCause(
356
- parent,
357
- new Date(Date.now() + timeout / 1000000),
358
- cause,
359
- )
355
+ return WithDeadlineCause(parent, time.Now().Add(timeout), cause)
360
356
  }
361
357
 
362
358
  // WithValue returns a copy of parent with the value associated with key
@@ -409,7 +405,7 @@ export function AfterFunc(ctx: Context, f: () => void): () => boolean {
409
405
  if (!stopped) {
410
406
  done = true
411
407
  // Run in next tick to simulate goroutine
412
- setImmediate(f)
408
+ queueMicrotask(f)
413
409
  }
414
410
  })()
415
411
 
@@ -0,0 +1 @@
1
+ export * from '@goscript/internal/byteorder/index.js'
@@ -0,0 +1 @@
1
+ export { New, Setting, Value } from '@goscript/internal/godebug/index.js'
@@ -0,0 +1,32 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import * as $ from '@goscript/builtin/index.js'
4
+
5
+ import { Read, Reader, Text } from './index.js'
6
+
7
+ describe('crypto/rand override', () => {
8
+ it('fills byte slices from Web Crypto', () => {
9
+ const buf = new Uint8Array(32)
10
+ const [n, err] = Read(buf)
11
+
12
+ expect(err).toBeNull()
13
+ expect(n).toBe(32)
14
+ expect(buf.some((b) => b !== 0)).toBe(true)
15
+ })
16
+
17
+ it('exposes Reader as an io.Reader-compatible source', () => {
18
+ const buf = $.makeSlice<number>(12, 12, 'byte')
19
+ const [n, err] = Reader.Read(buf)
20
+
21
+ expect(err).toBeNull()
22
+ expect(n).toBe(12)
23
+ expect(Array.from(buf ?? []).some((b) => b !== 0)).toBe(true)
24
+ })
25
+
26
+ it('generates base32 text tokens', () => {
27
+ const token = Text()
28
+
29
+ expect(token).toHaveLength(26)
30
+ expect(token).toMatch(/^[A-Z2-7]+$/)
31
+ })
32
+ })
@@ -0,0 +1,90 @@
1
+ import * as $ from '@goscript/builtin/index.js'
2
+ import * as io from '@goscript/io/index.js'
3
+
4
+ const base32alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'
5
+ const maxGetRandomValuesBytes = 65536
6
+
7
+ class RandError {
8
+ constructor(private readonly message: string) {}
9
+
10
+ Error(): string {
11
+ return this.message
12
+ }
13
+ }
14
+
15
+ class WebCryptoReader implements io.Reader {
16
+ Read(p: $.Bytes): [number, $.GoError] {
17
+ const err = fillSecureBytes(p)
18
+ if (err != null) {
19
+ return [0, err]
20
+ }
21
+ return [$.len(p), null]
22
+ }
23
+ }
24
+
25
+ export let Reader: io.Reader = new WebCryptoReader()
26
+
27
+ export function Read(b: $.Bytes): [number, $.GoError] {
28
+ const [n, err] = Reader.Read(b)
29
+ if (err != null) {
30
+ return [n, err]
31
+ }
32
+ if (n !== $.len(b)) {
33
+ return [n, io.ErrUnexpectedEOF]
34
+ }
35
+ return [n, null]
36
+ }
37
+
38
+ export function Text(): string {
39
+ const src = new Uint8Array(26)
40
+ const [, err] = Read(src)
41
+ if (err != null) {
42
+ throw new Error(err.Error())
43
+ }
44
+
45
+ let out = ''
46
+ for (const b of src) {
47
+ out += base32alphabet[b % 32]
48
+ }
49
+ return out
50
+ }
51
+
52
+ function fillSecureBytes(dst: $.Bytes): $.GoError {
53
+ const length = $.len(dst)
54
+ if (length === 0) {
55
+ return null
56
+ }
57
+
58
+ const crypto = secureCrypto()
59
+ if (crypto == null) {
60
+ return new RandError('crypto/rand: Web Crypto getRandomValues is unavailable')
61
+ }
62
+
63
+ if (dst instanceof Uint8Array) {
64
+ fillUint8Array(crypto, dst)
65
+ return null
66
+ }
67
+
68
+ const tmp = new Uint8Array(length)
69
+ fillUint8Array(crypto, tmp)
70
+ $.copy(dst, tmp)
71
+ return null
72
+ }
73
+
74
+ function fillUint8Array(crypto: Crypto, dst: Uint8Array): void {
75
+ for (let offset = 0; offset < dst.length; offset += maxGetRandomValuesBytes) {
76
+ const chunk = dst.subarray(
77
+ offset,
78
+ Math.min(offset + maxGetRandomValuesBytes, dst.length),
79
+ ) as Uint8Array<ArrayBuffer>
80
+ crypto.getRandomValues(chunk)
81
+ }
82
+ }
83
+
84
+ function secureCrypto(): Crypto | null {
85
+ const crypto = globalThis.crypto
86
+ if (crypto && typeof crypto.getRandomValues === 'function') {
87
+ return crypto
88
+ }
89
+ return null
90
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependencies": [
3
+ "io"
4
+ ]
5
+ }
@@ -0,0 +1,20 @@
1
+ import * as $ from '@goscript/builtin/index.js'
2
+ import * as fs from '@goscript/io/fs/index.js'
3
+
4
+ export class FS {
5
+ Open(name: string): [fs.File, $.GoError] {
6
+ return [null, pathError('open', name)]
7
+ }
8
+
9
+ ReadDir(name: string): [$.Slice<fs.DirEntry>, $.GoError] {
10
+ return [null, pathError('read', name)]
11
+ }
12
+
13
+ ReadFile(name: string): [Uint8Array, $.GoError] {
14
+ return [new Uint8Array(0), pathError('read', name)]
15
+ }
16
+ }
17
+
18
+ function pathError(op: string, name: string): $.GoError {
19
+ return new fs.PathError({ Op: op, Path: name, Err: fs.ErrNotExist })
20
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependencies": [
3
+ "io/fs"
4
+ ]
5
+ }
@@ -0,0 +1,79 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import * as $ from '@goscript/builtin/index.js'
4
+
5
+ import { Marshal, MarshalIndent, Unmarshal } from './index.js'
6
+
7
+ class Person {
8
+ public _fields = {
9
+ Name: $.varRef(''),
10
+ Age: $.varRef(0),
11
+ Active: $.varRef(false),
12
+ }
13
+
14
+ static __typeInfo = $.registerStructType(
15
+ 'test.Person',
16
+ new Person(),
17
+ [],
18
+ Person,
19
+ {
20
+ Name: { type: { kind: $.TypeKind.Basic, name: 'string' }, tag: 'json:"name"' },
21
+ Age: { type: { kind: $.TypeKind.Basic, name: 'int' }, tag: 'json:"age"' },
22
+ Active: { type: { kind: $.TypeKind.Basic, name: 'bool' }, tag: 'json:"active"' },
23
+ },
24
+ )
25
+ }
26
+
27
+ describe('encoding/json override', () => {
28
+ it('marshals struct fields through json tags', () => {
29
+ const person = new Person()
30
+ person._fields.Name.value = 'Alice'
31
+ person._fields.Age.value = 30
32
+ person._fields.Active.value = true
33
+
34
+ const [data, err] = Marshal(person)
35
+
36
+ expect(err).toBeNull()
37
+ expect($.bytesToString(data)).toBe(
38
+ '{"name":"Alice","age":30,"active":true}',
39
+ )
40
+ })
41
+
42
+ it('marshals indented JSON with a line prefix', () => {
43
+ const person = new Person()
44
+ person._fields.Name.value = 'Alice'
45
+ person._fields.Age.value = 30
46
+ person._fields.Active.value = true
47
+
48
+ const [data, err] = MarshalIndent(person, '> ', ' ')
49
+
50
+ expect(err).toBeNull()
51
+ expect($.bytesToString(data)).toBe(
52
+ '{\n> "name": "Alice",\n> "age": 30,\n> "active": true\n> }',
53
+ )
54
+ })
55
+
56
+ it('unmarshals into struct and map pointers', () => {
57
+ const person = $.varRef(new Person())
58
+ const personErr = Unmarshal(
59
+ $.stringToBytes('{"name":"Bob","age":25,"active":false}'),
60
+ person,
61
+ )
62
+
63
+ expect(personErr).toBeNull()
64
+ expect(person.value._fields.Name.value).toBe('Bob')
65
+ expect(person.value._fields.Age.value).toBe(25)
66
+ expect(person.value._fields.Active.value).toBe(false)
67
+
68
+ const mapRef: $.VarRef<Map<string, unknown> | null> = $.varRef(null)
69
+ const mapErr = Unmarshal(
70
+ $.stringToBytes('{"name":"Carol","age":22,"active":true}'),
71
+ mapRef,
72
+ )
73
+
74
+ expect(mapErr).toBeNull()
75
+ expect(mapRef.value?.get('name')).toBe('Carol')
76
+ expect(mapRef.value?.get('age')).toBe(22)
77
+ expect(mapRef.value?.get('active')).toBe(true)
78
+ })
79
+ })
@@ -0,0 +1,210 @@
1
+ import * as $ from '@goscript/builtin/index.js'
2
+
3
+ export function Marshal(v: unknown): [$.Slice<number>, $.GoError] {
4
+ try {
5
+ return [$.stringToBytes(JSON.stringify(marshalValue(v))), null]
6
+ } catch (err) {
7
+ return [null, goError(err)]
8
+ }
9
+ }
10
+
11
+ export function MarshalIndent(
12
+ v: unknown,
13
+ prefix: string,
14
+ indent: string,
15
+ ): [$.Slice<number>, $.GoError] {
16
+ try {
17
+ const text = JSON.stringify(marshalValue(v), null, indent)
18
+ if (prefix === '') {
19
+ return [$.stringToBytes(text), null]
20
+ }
21
+ return [
22
+ $.stringToBytes(
23
+ text
24
+ .split('\n')
25
+ .map((line, idx) => (idx === 0 ? line : prefix + line))
26
+ .join('\n'),
27
+ ),
28
+ null,
29
+ ]
30
+ } catch (err) {
31
+ return [null, goError(err)]
32
+ }
33
+ }
34
+
35
+ export function Unmarshal(data: $.Slice<number>, v: unknown): $.GoError {
36
+ try {
37
+ assignDecodedValue(v, JSON.parse($.bytesToString(data)))
38
+ return null
39
+ } catch (err) {
40
+ return goError(err)
41
+ }
42
+ }
43
+
44
+ function marshalValue(v: unknown): unknown {
45
+ if ($.isVarRef(v)) {
46
+ return marshalValue(v.value)
47
+ }
48
+ if (v === null || v === undefined) {
49
+ return null
50
+ }
51
+ if (typeof v !== 'object') {
52
+ return v
53
+ }
54
+ if (v instanceof Uint8Array) {
55
+ return Array.from(v).map(marshalValue)
56
+ }
57
+ if (Array.isArray(v)) {
58
+ return v.map(marshalValue)
59
+ }
60
+ if (v instanceof Map) {
61
+ const out: Record<string, unknown> = {}
62
+ for (const [key, value] of v.entries()) {
63
+ out[String(key)] = marshalValue(value)
64
+ }
65
+ return out
66
+ }
67
+ if (!isStructValue(v)) {
68
+ return v
69
+ }
70
+
71
+ const out: Record<string, unknown> = {}
72
+ const typeFields = structFieldMetadata(v)
73
+ for (const [fieldName, ref] of Object.entries(v._fields)) {
74
+ const jsonName = jsonFieldName(fieldName, typeFields[fieldName]?.tag)
75
+ if (jsonName === '') {
76
+ continue
77
+ }
78
+ out[jsonName] = marshalValue(ref.value)
79
+ }
80
+ return out
81
+ }
82
+
83
+ function assignDecodedValue(target: unknown, decoded: unknown): void {
84
+ if ($.isVarRef(target)) {
85
+ if (isStructValue(target.value) && isPlainObject(decoded)) {
86
+ assignStructFields(target.value, decoded)
87
+ return
88
+ }
89
+ if (isPlainObject(decoded)) {
90
+ target.value = objectToMap(decoded)
91
+ return
92
+ }
93
+ target.value = decoded
94
+ return
95
+ }
96
+ if (isStructValue(target) && isPlainObject(decoded)) {
97
+ assignStructFields(target, decoded)
98
+ }
99
+ }
100
+
101
+ function assignStructFields(
102
+ target: { _fields: Record<string, $.VarRef<unknown>> },
103
+ decoded: Record<string, unknown>,
104
+ ): void {
105
+ const typeFields = structFieldMetadata(target)
106
+ for (const [fieldName, ref] of Object.entries(target._fields)) {
107
+ const jsonName = jsonFieldName(fieldName, typeFields[fieldName]?.tag)
108
+ if (
109
+ jsonName !== '' &&
110
+ Object.prototype.hasOwnProperty.call(decoded, jsonName)
111
+ ) {
112
+ ref.value = decoded[jsonName]
113
+ }
114
+ }
115
+ }
116
+
117
+ function objectToMap(decoded: Record<string, unknown>): Map<string, unknown> {
118
+ const out = new Map<string, unknown>()
119
+ for (const [key, value] of Object.entries(decoded)) {
120
+ out.set(key, isPlainObject(value) ? objectToMap(value) : value)
121
+ }
122
+ return out
123
+ }
124
+
125
+ function isStructValue(
126
+ value: unknown,
127
+ ): value is { _fields: Record<string, $.VarRef<unknown>> } {
128
+ if (value === null || typeof value !== 'object') {
129
+ return false
130
+ }
131
+ const fields = Reflect.get(value, '_fields')
132
+ return (
133
+ fields !== null &&
134
+ fields !== undefined &&
135
+ typeof fields === 'object' &&
136
+ !Array.isArray(fields)
137
+ )
138
+ }
139
+
140
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
141
+ return (
142
+ value !== null &&
143
+ typeof value === 'object' &&
144
+ !Array.isArray(value) &&
145
+ !(value instanceof Uint8Array) &&
146
+ !(value instanceof Map)
147
+ )
148
+ }
149
+
150
+ function structFieldMetadata(
151
+ value: unknown,
152
+ ): Record<string, { tag?: string }> {
153
+ if (value === null || typeof value !== 'object') {
154
+ return {}
155
+ }
156
+ const ctor = Reflect.get(value, 'constructor')
157
+ if (
158
+ ctor === null ||
159
+ ctor === undefined ||
160
+ (typeof ctor !== 'object' && typeof ctor !== 'function')
161
+ ) {
162
+ return {}
163
+ }
164
+ const typeInfo = Reflect.get(ctor, '__typeInfo')
165
+ if (
166
+ typeInfo === null ||
167
+ typeInfo === undefined ||
168
+ typeof typeInfo !== 'object'
169
+ ) {
170
+ return {}
171
+ }
172
+ const fields = Reflect.get(typeInfo, 'fields')
173
+ if (isPlainObject(fields)) {
174
+ const out: Record<string, { tag?: string }> = {}
175
+ for (const [name, field] of Object.entries(fields)) {
176
+ if (!isPlainObject(field)) {
177
+ continue
178
+ }
179
+ const tag = field.tag
180
+ out[name] = typeof tag === 'string' ? { tag } : {}
181
+ }
182
+ return out
183
+ }
184
+ return {}
185
+ }
186
+
187
+ function goError(err: unknown): $.GoError {
188
+ if (err instanceof Error) {
189
+ return $.toGoError(err)
190
+ }
191
+ return $.newError(String(err))
192
+ }
193
+
194
+ function jsonFieldName(fieldName: string, tag: string | undefined): string {
195
+ if (tag === undefined || !tag.startsWith('json:"')) {
196
+ return fieldName
197
+ }
198
+ const end = tag.indexOf('"', 'json:"'.length)
199
+ if (end < 0) {
200
+ return fieldName
201
+ }
202
+ const name = tag.slice('json:"'.length, end).split(',')[0]
203
+ if (name === '-') {
204
+ return ''
205
+ }
206
+ if (name === '') {
207
+ return fieldName
208
+ }
209
+ return name
210
+ }
@@ -0,0 +1,82 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import * as $ from '@goscript/builtin/index.js'
4
+
5
+ import { AsType, Errorf, Is, Join, Wrap, Wrapf } from './errors.js'
6
+
7
+ class DNSError {
8
+ public readonly IsNotFound = true
9
+
10
+ public Error(): string {
11
+ return 'dns'
12
+ }
13
+ }
14
+
15
+ class Wrapper {
16
+ constructor(private readonly err: $.GoError) {}
17
+
18
+ public Error(): string {
19
+ return 'wrapped'
20
+ }
21
+
22
+ public Unwrap(): $.GoError {
23
+ return this.err
24
+ }
25
+ }
26
+
27
+ const dnsTypeArgs: $.GenericTypeArgs = {
28
+ E: {
29
+ type: { kind: $.TypeKind.Pointer, elemType: 'net.DNSError' },
30
+ zero: () => null,
31
+ },
32
+ }
33
+
34
+ describe('errors.AsType', () => {
35
+ it('returns a directly matching error', () => {
36
+ const dns = $.interfaceValue<$.GoError>(new DNSError(), '*net.DNSError')
37
+
38
+ const [matched, ok] = AsType(dnsTypeArgs, dns)
39
+
40
+ expect(ok).toBe(true)
41
+ expect(matched).toBe(dns)
42
+ })
43
+
44
+ it('walks wrapped errors depth first', () => {
45
+ const dns = $.interfaceValue<$.GoError>(new DNSError(), '*net.DNSError')
46
+ const wrapped = $.interfaceValue<$.GoError>(new Wrapper(dns), '*main.Wrapper')
47
+
48
+ const [matched, ok] = AsType(dnsTypeArgs, Join(null, wrapped))
49
+
50
+ expect(ok).toBe(true)
51
+ expect(matched).toBe(dns)
52
+ })
53
+
54
+ it('returns zero when no error matches', () => {
55
+ const [matched, ok] = AsType(dnsTypeArgs, $.newError('plain'))
56
+
57
+ expect(ok).toBe(false)
58
+ expect(matched).toBe(null)
59
+ })
60
+ })
61
+
62
+ describe('errors github.com/pkg/errors compatibility helpers', () => {
63
+ it('formats new errors', () => {
64
+ expect(Errorf('bad %s: %d', 'value', 42)?.Error()).toBe('bad value: 42')
65
+ })
66
+
67
+ it('wraps and unwraps errors', () => {
68
+ const base = $.newError('root')
69
+ const wrapped = Wrap(base, 'context')
70
+
71
+ expect(wrapped?.Error()).toBe('context: root')
72
+ expect(Is(wrapped, base)).toBe(true)
73
+ })
74
+
75
+ it('wraps formatted context and preserves nil', () => {
76
+ const base = $.newError('root')
77
+
78
+ expect(Wrapf(base, 'context %d', 7)?.Error()).toBe('context 7: root')
79
+ expect(Wrap(null, 'context')).toBe(null)
80
+ expect(Wrapf(null, 'context %d', 7)).toBe(null)
81
+ })
82
+ })