goscript 0.1.0 → 0.1.2

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 (495) hide show
  1. package/README.md +267 -255
  2. package/cmd/goscript/cmd-test.go +286 -0
  3. package/cmd/goscript/cmd-test_test.go +76 -0
  4. package/cmd/goscript/cmd_compile.go +9 -0
  5. package/cmd/goscript/main.go +1 -0
  6. package/compiler/build-flags.go +38 -0
  7. package/compiler/compile-request.go +33 -0
  8. package/compiler/compiler.go +1 -1
  9. package/compiler/compliance_test.go +0 -10
  10. package/compiler/config.go +2 -0
  11. package/compiler/gotest/owner.go +24 -0
  12. package/compiler/gotest/package-result.go +69 -0
  13. package/compiler/gotest/request.go +210 -0
  14. package/compiler/gotest/result.go +28 -0
  15. package/compiler/gotest/runner.go +1225 -0
  16. package/compiler/gotest/runner_test.go +1271 -0
  17. package/compiler/gotest/test.go +9 -0
  18. package/compiler/index.test.ts +1 -1
  19. package/compiler/lowered-program.go +80 -21
  20. package/compiler/lowering.go +6754 -602
  21. package/compiler/override-facts.go +357 -0
  22. package/compiler/override-registry.go +52 -190
  23. package/compiler/override-registry_test.go +182 -0
  24. package/compiler/package-graph.go +50 -27
  25. package/compiler/package-graph_test.go +99 -9
  26. package/compiler/package-test-function.go +9 -0
  27. package/compiler/package-test-graph-package.go +40 -0
  28. package/compiler/package-test-graph-variant.go +129 -0
  29. package/compiler/package-test-graph.go +112 -0
  30. package/compiler/package-test-graph_test.go +202 -0
  31. package/compiler/runtime-contract.go +229 -29
  32. package/compiler/runtime-contract_test.go +44 -30
  33. package/compiler/semantic-model-types.go +25 -6
  34. package/compiler/semantic-model.go +819 -74
  35. package/compiler/semantic-model_test.go +104 -0
  36. package/compiler/service.go +10 -4
  37. package/compiler/skeleton_test.go +2777 -524
  38. package/compiler/tsworkspace/owner-process-unix_test.go +72 -0
  39. package/compiler/tsworkspace/owner.go +342 -0
  40. package/compiler/tsworkspace/owner_test.go +93 -0
  41. package/compiler/tsworkspace/result.go +17 -0
  42. package/compiler/tsworkspace/tool-process-other.go +14 -0
  43. package/compiler/tsworkspace/tool-process-unix.go +19 -0
  44. package/compiler/typescript-emitter.go +576 -86
  45. package/compiler/wasm/compile.go +1 -1
  46. package/compiler/wasm/compile_test.go +61 -11
  47. package/compiler/wasm_api.go +172 -7
  48. package/dist/gs/builtin/builtin.d.ts +40 -3
  49. package/dist/gs/builtin/builtin.js +430 -22
  50. package/dist/gs/builtin/builtin.js.map +1 -1
  51. package/dist/gs/builtin/channel.d.ts +32 -10
  52. package/dist/gs/builtin/channel.js +119 -25
  53. package/dist/gs/builtin/channel.js.map +1 -1
  54. package/dist/gs/builtin/defer.d.ts +1 -0
  55. package/dist/gs/builtin/defer.js +12 -2
  56. package/dist/gs/builtin/defer.js.map +1 -1
  57. package/dist/gs/builtin/hostio.d.ts +9 -0
  58. package/dist/gs/builtin/hostio.js +25 -0
  59. package/dist/gs/builtin/hostio.js.map +1 -1
  60. package/dist/gs/builtin/map.js +40 -6
  61. package/dist/gs/builtin/map.js.map +1 -1
  62. package/dist/gs/builtin/print.js.map +1 -1
  63. package/dist/gs/builtin/slice.d.ts +64 -10
  64. package/dist/gs/builtin/slice.js +619 -244
  65. package/dist/gs/builtin/slice.js.map +1 -1
  66. package/dist/gs/builtin/type.d.ts +7 -2
  67. package/dist/gs/builtin/type.js +128 -29
  68. package/dist/gs/builtin/type.js.map +1 -1
  69. package/dist/gs/builtin/varRef.d.ts +7 -0
  70. package/dist/gs/builtin/varRef.js +23 -0
  71. package/dist/gs/builtin/varRef.js.map +1 -1
  72. package/dist/gs/bytes/buffer.gs.js +74 -70
  73. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  74. package/dist/gs/bytes/iter.gs.js +13 -13
  75. package/dist/gs/bytes/iter.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/compress/zlib/index.d.ts +26 -0
  79. package/dist/gs/compress/zlib/index.js +168 -0
  80. package/dist/gs/compress/zlib/index.js.map +1 -0
  81. package/dist/gs/context/context.d.ts +6 -5
  82. package/dist/gs/context/context.js +17 -12
  83. package/dist/gs/context/context.js.map +1 -1
  84. package/dist/gs/crypto/ecdh/index.d.ts +52 -0
  85. package/dist/gs/crypto/ecdh/index.js +226 -0
  86. package/dist/gs/crypto/ecdh/index.js.map +1 -0
  87. package/dist/gs/crypto/ed25519/index.d.ts +34 -0
  88. package/dist/gs/crypto/ed25519/index.js +160 -0
  89. package/dist/gs/crypto/ed25519/index.js.map +1 -0
  90. package/dist/gs/crypto/internal/constanttime/index.d.ts +4 -0
  91. package/dist/gs/crypto/internal/constanttime/index.js +18 -0
  92. package/dist/gs/crypto/internal/constanttime/index.js.map +1 -0
  93. package/dist/gs/crypto/internal/fips140deps/byteorder/index.d.ts +1 -0
  94. package/dist/gs/crypto/internal/fips140deps/byteorder/index.js +2 -0
  95. package/dist/gs/crypto/internal/fips140deps/byteorder/index.js.map +1 -0
  96. package/dist/gs/crypto/internal/fips140deps/godebug/index.d.ts +1 -0
  97. package/dist/gs/crypto/internal/fips140deps/godebug/index.js +2 -0
  98. package/dist/gs/crypto/internal/fips140deps/godebug/index.js.map +1 -0
  99. package/dist/gs/crypto/rand/index.d.ts +2 -0
  100. package/dist/gs/crypto/rand/index.js +85 -0
  101. package/dist/gs/crypto/rand/index.js.map +1 -1
  102. package/dist/gs/crypto/sha256/index.d.ts +8 -0
  103. package/dist/gs/crypto/sha256/index.js +118 -0
  104. package/dist/gs/crypto/sha256/index.js.map +1 -0
  105. package/dist/gs/crypto/sha512/index.d.ts +14 -0
  106. package/dist/gs/crypto/sha512/index.js +129 -0
  107. package/dist/gs/crypto/sha512/index.js.map +1 -0
  108. package/dist/gs/embed/index.d.ts +7 -0
  109. package/dist/gs/embed/index.js +16 -0
  110. package/dist/gs/embed/index.js.map +1 -0
  111. package/dist/gs/encoding/json/index.d.ts +4 -0
  112. package/dist/gs/encoding/json/index.js +33 -0
  113. package/dist/gs/encoding/json/index.js.map +1 -1
  114. package/dist/gs/errors/errors.d.ts +4 -0
  115. package/dist/gs/errors/errors.js +108 -4
  116. package/dist/gs/errors/errors.js.map +1 -1
  117. package/dist/gs/fmt/fmt.d.ts +4 -4
  118. package/dist/gs/fmt/fmt.js +42 -11
  119. package/dist/gs/fmt/fmt.js.map +1 -1
  120. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +37 -2
  121. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +245 -1
  122. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  123. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +189 -0
  124. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +861 -0
  125. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -0
  126. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +217 -0
  127. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +814 -0
  128. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -0
  129. package/dist/gs/github.com/aperturerobotics/util/conc/index.d.ts +20 -0
  130. package/dist/gs/github.com/aperturerobotics/util/conc/index.js +134 -0
  131. package/dist/gs/github.com/aperturerobotics/util/conc/index.js.map +1 -0
  132. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
  133. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.d.ts +3 -0
  134. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js +50 -0
  135. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js.map +1 -0
  136. package/dist/gs/github.com/klauspost/compress/internal/le/index.d.ts +9 -0
  137. package/dist/gs/github.com/klauspost/compress/internal/le/index.js +72 -0
  138. package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -0
  139. package/dist/gs/github.com/mr-tron/base58/base58/index.d.ts +27 -0
  140. package/dist/gs/github.com/mr-tron/base58/base58/index.js +172 -0
  141. package/dist/gs/github.com/mr-tron/base58/base58/index.js.map +1 -0
  142. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.d.ts +21 -0
  143. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js +22 -0
  144. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js.map +1 -0
  145. package/dist/gs/go/internal/scannerhooks/index.d.ts +3 -0
  146. package/dist/gs/go/internal/scannerhooks/index.js +5 -0
  147. package/dist/gs/go/internal/scannerhooks/index.js.map +1 -0
  148. package/dist/gs/go/scanner/index.d.ts +13 -0
  149. package/dist/gs/go/scanner/index.js +35 -0
  150. package/dist/gs/go/scanner/index.js.map +1 -1
  151. package/dist/gs/go/token/index.d.ts +156 -0
  152. package/dist/gs/go/token/index.js +507 -4
  153. package/dist/gs/go/token/index.js.map +1 -1
  154. package/dist/gs/hash/fnv/index.d.ts +57 -0
  155. package/dist/gs/hash/fnv/index.js +299 -0
  156. package/dist/gs/hash/fnv/index.js.map +1 -0
  157. package/dist/gs/hash/index.d.ts +17 -0
  158. package/dist/gs/hash/index.js +94 -0
  159. package/dist/gs/hash/index.js.map +1 -0
  160. package/dist/gs/internal/abi/index.d.ts +4 -0
  161. package/dist/gs/internal/abi/index.js +10 -0
  162. package/dist/gs/internal/abi/index.js.map +1 -1
  163. package/dist/gs/internal/bytealg/index.d.ts +2 -0
  164. package/dist/gs/internal/bytealg/index.js +14 -0
  165. package/dist/gs/internal/bytealg/index.js.map +1 -1
  166. package/dist/gs/internal/byteorder/index.d.ts +8 -2
  167. package/dist/gs/internal/byteorder/index.js +56 -25
  168. package/dist/gs/internal/byteorder/index.js.map +1 -1
  169. package/dist/gs/internal/godebug/index.d.ts +12 -0
  170. package/dist/gs/internal/godebug/index.js +30 -0
  171. package/dist/gs/internal/godebug/index.js.map +1 -0
  172. package/dist/gs/io/fs/index.d.ts +1 -0
  173. package/dist/gs/io/fs/index.js +1 -0
  174. package/dist/gs/io/fs/index.js.map +1 -1
  175. package/dist/gs/io/fs/readlink.d.ts +8 -0
  176. package/dist/gs/io/fs/readlink.js +60 -0
  177. package/dist/gs/io/fs/readlink.js.map +1 -0
  178. package/dist/gs/io/fs/walk.d.ts +3 -3
  179. package/dist/gs/io/fs/walk.js +7 -7
  180. package/dist/gs/io/fs/walk.js.map +1 -1
  181. package/dist/gs/io/io.d.ts +40 -6
  182. package/dist/gs/io/io.js +151 -26
  183. package/dist/gs/io/io.js.map +1 -1
  184. package/dist/gs/iter/iter.d.ts +3 -2
  185. package/dist/gs/iter/iter.js.map +1 -1
  186. package/dist/gs/maps/iter.d.ts +5 -5
  187. package/dist/gs/maps/iter.js +48 -21
  188. package/dist/gs/maps/iter.js.map +1 -1
  189. package/dist/gs/maps/maps.d.ts +6 -6
  190. package/dist/gs/maps/maps.js +1 -1
  191. package/dist/gs/maps/maps.js.map +1 -1
  192. package/dist/gs/math/bits/index.d.ts +13 -4
  193. package/dist/gs/math/bits/index.js +70 -48
  194. package/dist/gs/math/bits/index.js.map +1 -1
  195. package/dist/gs/math/const.gs.d.ts +5 -5
  196. package/dist/gs/math/const.gs.js +4 -4
  197. package/dist/gs/math/const.gs.js.map +1 -1
  198. package/dist/gs/mime/index.d.ts +1 -0
  199. package/dist/gs/mime/index.js +52 -0
  200. package/dist/gs/mime/index.js.map +1 -0
  201. package/dist/gs/net/http/httptest/index.d.ts +30 -0
  202. package/dist/gs/net/http/httptest/index.js +101 -0
  203. package/dist/gs/net/http/httptest/index.js.map +1 -0
  204. package/dist/gs/net/http/index.d.ts +131 -0
  205. package/dist/gs/net/http/index.js +307 -0
  206. package/dist/gs/net/http/index.js.map +1 -0
  207. package/dist/gs/net/http/pprof/index.d.ts +8 -0
  208. package/dist/gs/net/http/pprof/index.js +59 -0
  209. package/dist/gs/net/http/pprof/index.js.map +1 -0
  210. package/dist/gs/os/dir_unix.gs.js +2 -2
  211. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  212. package/dist/gs/os/error.gs.js +9 -7
  213. package/dist/gs/os/error.gs.js.map +1 -1
  214. package/dist/gs/os/types_js.gs.js +95 -15
  215. package/dist/gs/os/types_js.gs.js.map +1 -1
  216. package/dist/gs/path/filepath/match.js +165 -3
  217. package/dist/gs/path/filepath/match.js.map +1 -1
  218. package/dist/gs/path/filepath/path.d.ts +8 -4
  219. package/dist/gs/path/filepath/path.js +192 -8
  220. package/dist/gs/path/filepath/path.js.map +1 -1
  221. package/dist/gs/path/path.d.ts +4 -1
  222. package/dist/gs/path/path.js +16 -4
  223. package/dist/gs/path/path.js.map +1 -1
  224. package/dist/gs/reflect/index.d.ts +4 -3
  225. package/dist/gs/reflect/index.js +3 -2
  226. package/dist/gs/reflect/index.js.map +1 -1
  227. package/dist/gs/reflect/iter.js +2 -2
  228. package/dist/gs/reflect/iter.js.map +1 -1
  229. package/dist/gs/reflect/map.js +29 -0
  230. package/dist/gs/reflect/map.js.map +1 -1
  231. package/dist/gs/reflect/type.d.ts +31 -9
  232. package/dist/gs/reflect/type.js +536 -43
  233. package/dist/gs/reflect/type.js.map +1 -1
  234. package/dist/gs/reflect/types.d.ts +1 -0
  235. package/dist/gs/reflect/types.js +3 -1
  236. package/dist/gs/reflect/types.js.map +1 -1
  237. package/dist/gs/reflect/value.d.ts +4 -1
  238. package/dist/gs/reflect/value.js +39 -1
  239. package/dist/gs/reflect/value.js.map +1 -1
  240. package/dist/gs/reflect/visiblefields.js +1 -1
  241. package/dist/gs/reflect/visiblefields.js.map +1 -1
  242. package/dist/gs/runtime/debug/index.d.ts +41 -0
  243. package/dist/gs/runtime/debug/index.js +66 -0
  244. package/dist/gs/runtime/debug/index.js.map +1 -0
  245. package/dist/gs/runtime/pprof/index.d.ts +20 -0
  246. package/dist/gs/runtime/pprof/index.js +85 -0
  247. package/dist/gs/runtime/pprof/index.js.map +1 -0
  248. package/dist/gs/runtime/runtime.d.ts +35 -3
  249. package/dist/gs/runtime/runtime.js +72 -0
  250. package/dist/gs/runtime/runtime.js.map +1 -1
  251. package/dist/gs/runtime/trace/index.d.ts +19 -0
  252. package/dist/gs/runtime/trace/index.js +64 -0
  253. package/dist/gs/runtime/trace/index.js.map +1 -0
  254. package/dist/gs/slices/slices.d.ts +42 -8
  255. package/dist/gs/slices/slices.js +425 -11
  256. package/dist/gs/slices/slices.js.map +1 -1
  257. package/dist/gs/sort/slice.gs.d.ts +5 -3
  258. package/dist/gs/sort/slice.gs.js +60 -22
  259. package/dist/gs/sort/slice.gs.js.map +1 -1
  260. package/dist/gs/sort/sort.gs.d.ts +4 -4
  261. package/dist/gs/sort/sort.gs.js +11 -8
  262. package/dist/gs/sort/sort.gs.js.map +1 -1
  263. package/dist/gs/strings/builder.d.ts +1 -1
  264. package/dist/gs/strings/builder.js +29 -19
  265. package/dist/gs/strings/builder.js.map +1 -1
  266. package/dist/gs/strings/iter.js +140 -75
  267. package/dist/gs/strings/iter.js.map +1 -1
  268. package/dist/gs/strings/replace.js +2 -2
  269. package/dist/gs/strings/replace.js.map +1 -1
  270. package/dist/gs/strings/strings.js +52 -6
  271. package/dist/gs/strings/strings.js.map +1 -1
  272. package/dist/gs/sync/atomic/type.gs.d.ts +9 -8
  273. package/dist/gs/sync/atomic/type.gs.js +0 -2
  274. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  275. package/dist/gs/sync/sync.d.ts +8 -3
  276. package/dist/gs/sync/sync.js +66 -11
  277. package/dist/gs/sync/sync.js.map +1 -1
  278. package/dist/gs/syscall/constants.d.ts +36 -24
  279. package/dist/gs/syscall/constants.js +12 -0
  280. package/dist/gs/syscall/constants.js.map +1 -1
  281. package/dist/gs/syscall/errors.d.ts +117 -111
  282. package/dist/gs/syscall/errors.js +45 -0
  283. package/dist/gs/syscall/errors.js.map +1 -1
  284. package/dist/gs/syscall/fs.d.ts +37 -0
  285. package/dist/gs/syscall/fs.js +102 -0
  286. package/dist/gs/syscall/fs.js.map +1 -1
  287. package/dist/gs/syscall/js/index.d.ts +90 -0
  288. package/dist/gs/syscall/js/index.js +383 -0
  289. package/dist/gs/syscall/js/index.js.map +1 -0
  290. package/dist/gs/syscall/types.d.ts +26 -1
  291. package/dist/gs/syscall/types.js +45 -1
  292. package/dist/gs/syscall/types.js.map +1 -1
  293. package/dist/gs/testing/index.d.ts +1 -0
  294. package/dist/gs/testing/index.js +2 -0
  295. package/dist/gs/testing/index.js.map +1 -0
  296. package/dist/gs/testing/testing.d.ts +78 -0
  297. package/dist/gs/testing/testing.js +318 -0
  298. package/dist/gs/testing/testing.js.map +1 -0
  299. package/dist/gs/time/time.d.ts +41 -4
  300. package/dist/gs/time/time.js +227 -36
  301. package/dist/gs/time/time.js.map +1 -1
  302. package/dist/gs/unicode/unicode.d.ts +23 -1
  303. package/dist/gs/unicode/unicode.js +79 -10
  304. package/dist/gs/unicode/unicode.js.map +1 -1
  305. package/dist/gs/unicode/utf8/utf8.d.ts +4 -4
  306. package/dist/gs/unicode/utf8/utf8.js +24 -11
  307. package/dist/gs/unicode/utf8/utf8.js.map +1 -1
  308. package/dist/gs/unique/index.d.ts +11 -0
  309. package/dist/gs/unique/index.js +76 -0
  310. package/dist/gs/unique/index.js.map +1 -0
  311. package/go.mod +8 -8
  312. package/go.sum +14 -14
  313. package/gs/builtin/builtin.ts +585 -27
  314. package/gs/builtin/channel.ts +183 -29
  315. package/gs/builtin/defer.ts +13 -2
  316. package/gs/builtin/hostio.test.ts +1 -0
  317. package/gs/builtin/hostio.ts +38 -0
  318. package/gs/builtin/map.ts +46 -6
  319. package/gs/builtin/print.ts +12 -3
  320. package/gs/builtin/runtime-contract.test.ts +383 -10
  321. package/gs/builtin/slice.test.ts +70 -0
  322. package/gs/builtin/slice.ts +785 -265
  323. package/gs/builtin/type.ts +160 -41
  324. package/gs/builtin/varRef.ts +40 -1
  325. package/gs/bytes/buffer.gs.ts +74 -70
  326. package/gs/bytes/iter.gs.ts +13 -14
  327. package/gs/bytes/meta.json +8 -3
  328. package/gs/bytes/reader.gs.ts +20 -19
  329. package/gs/compress/zlib/index.test.ts +28 -0
  330. package/gs/compress/zlib/index.ts +200 -0
  331. package/gs/compress/zlib/meta.json +3 -0
  332. package/gs/context/context.test.ts +71 -0
  333. package/gs/context/context.ts +30 -29
  334. package/gs/crypto/ecdh/index.test.ts +43 -0
  335. package/gs/crypto/ecdh/index.ts +274 -0
  336. package/gs/crypto/ed25519/index.test.ts +41 -0
  337. package/gs/crypto/ed25519/index.ts +238 -0
  338. package/gs/crypto/ed25519/meta.json +13 -0
  339. package/gs/crypto/internal/constanttime/index.test.ts +25 -0
  340. package/gs/crypto/internal/constanttime/index.ts +22 -0
  341. package/gs/crypto/internal/fips140deps/byteorder/index.ts +1 -0
  342. package/gs/crypto/internal/fips140deps/godebug/index.ts +1 -0
  343. package/gs/crypto/rand/index.test.ts +89 -1
  344. package/gs/crypto/rand/index.ts +103 -1
  345. package/gs/crypto/rand/meta.json +4 -1
  346. package/gs/crypto/sha256/index.test.ts +78 -0
  347. package/gs/crypto/sha256/index.ts +150 -0
  348. package/gs/crypto/sha256/meta.json +9 -0
  349. package/gs/crypto/sha512/index.test.ts +31 -0
  350. package/gs/crypto/sha512/index.ts +161 -0
  351. package/gs/crypto/sha512/meta.json +11 -0
  352. package/gs/embed/index.ts +20 -0
  353. package/gs/embed/meta.json +5 -0
  354. package/gs/encoding/json/index.test.ts +39 -3
  355. package/gs/encoding/json/index.ts +45 -3
  356. package/gs/errors/errors.test.ts +85 -0
  357. package/gs/errors/errors.ts +132 -4
  358. package/gs/fmt/fmt.test.ts +3 -1
  359. package/gs/fmt/fmt.ts +55 -19
  360. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +128 -1
  361. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +342 -4
  362. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +180 -0
  363. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +1084 -0
  364. package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +31 -0
  365. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +1233 -0
  366. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +46 -0
  367. package/gs/github.com/aperturerobotics/util/conc/index.test.ts +30 -0
  368. package/gs/github.com/aperturerobotics/util/conc/index.ts +172 -0
  369. package/gs/github.com/aperturerobotics/util/conc/meta.json +9 -0
  370. package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.ts +1 -4
  371. package/gs/github.com/hack-pad/safejs/internal/catch/index.test.ts +35 -0
  372. package/gs/github.com/hack-pad/safejs/internal/catch/index.ts +65 -0
  373. package/gs/github.com/hack-pad/safejs/internal/catch/meta.json +9 -0
  374. package/gs/github.com/klauspost/compress/internal/le/index.test.ts +37 -0
  375. package/gs/github.com/klauspost/compress/internal/le/index.ts +115 -0
  376. package/gs/github.com/mr-tron/base58/base58/index.test.ts +70 -0
  377. package/gs/github.com/mr-tron/base58/base58/index.ts +231 -0
  378. package/gs/github.com/mr-tron/base58/base58/meta.json +3 -0
  379. package/gs/github.com/zeebo/blake3/internal/consts/index.test.ts +46 -0
  380. package/gs/github.com/zeebo/blake3/internal/consts/index.ts +26 -0
  381. package/gs/go/internal/scannerhooks/index.test.ts +14 -0
  382. package/gs/go/internal/scannerhooks/index.ts +9 -0
  383. package/gs/go/scanner/index.test.ts +22 -0
  384. package/gs/go/scanner/index.ts +47 -0
  385. package/gs/go/token/index.test.ts +47 -1
  386. package/gs/go/token/index.ts +583 -4
  387. package/gs/hash/fnv/index.test.ts +67 -0
  388. package/gs/hash/fnv/index.ts +351 -0
  389. package/gs/hash/fnv/meta.json +3 -0
  390. package/gs/hash/index.test.ts +37 -0
  391. package/gs/hash/index.ts +118 -0
  392. package/gs/hash/meta.json +5 -0
  393. package/gs/internal/abi/index.test.ts +18 -0
  394. package/gs/internal/abi/index.ts +14 -0
  395. package/gs/internal/bytealg/index.test.ts +18 -0
  396. package/gs/internal/bytealg/index.ts +16 -0
  397. package/gs/internal/byteorder/index.test.ts +39 -0
  398. package/gs/internal/byteorder/index.ts +100 -27
  399. package/gs/internal/godebug/index.test.ts +16 -0
  400. package/gs/internal/godebug/index.ts +35 -0
  401. package/gs/io/fs/index.ts +1 -0
  402. package/gs/io/fs/meta.json +5 -0
  403. package/gs/io/fs/readlink.test.ts +43 -0
  404. package/gs/io/fs/readlink.ts +69 -0
  405. package/gs/io/fs/walk.test.ts +61 -0
  406. package/gs/io/fs/walk.ts +17 -9
  407. package/gs/io/io.ts +177 -31
  408. package/gs/io/meta.json +10 -2
  409. package/gs/iter/iter.ts +8 -2
  410. package/gs/maps/iter.ts +75 -26
  411. package/gs/maps/maps.test.ts +23 -0
  412. package/gs/maps/maps.ts +13 -11
  413. package/gs/math/bits/index.test.ts +20 -0
  414. package/gs/math/bits/index.ts +107 -64
  415. package/gs/math/const.gs.test.ts +11 -5
  416. package/gs/math/const.gs.ts +5 -6
  417. package/gs/mime/index.ts +60 -0
  418. package/gs/net/http/httptest/index.test.ts +53 -0
  419. package/gs/net/http/httptest/index.ts +120 -0
  420. package/gs/net/http/index.test.ts +148 -0
  421. package/gs/net/http/index.ts +432 -0
  422. package/gs/net/http/meta.json +6 -0
  423. package/gs/net/http/pprof/index.test.ts +47 -0
  424. package/gs/net/http/pprof/index.ts +65 -0
  425. package/gs/os/dir_unix.gs.ts +2 -3
  426. package/gs/os/error.gs.ts +9 -10
  427. package/gs/os/error.test.ts +41 -0
  428. package/gs/os/file_unix_js.test.ts +55 -0
  429. package/gs/os/tempfile.gs.test.ts +37 -10
  430. package/gs/os/types_js.gs.ts +96 -17
  431. package/gs/path/filepath/match.test.ts +31 -12
  432. package/gs/path/filepath/match.ts +181 -3
  433. package/gs/path/filepath/meta.json +6 -0
  434. package/gs/path/filepath/path.test.ts +80 -0
  435. package/gs/path/filepath/path.ts +244 -11
  436. package/gs/path/path.ts +20 -5
  437. package/gs/reflect/field.test.ts +63 -0
  438. package/gs/reflect/index.ts +5 -1
  439. package/gs/reflect/iter.ts +2 -2
  440. package/gs/reflect/map.test.ts +42 -1
  441. package/gs/reflect/map.ts +39 -0
  442. package/gs/reflect/type.ts +728 -65
  443. package/gs/reflect/typefor.test.ts +100 -0
  444. package/gs/reflect/types.ts +3 -1
  445. package/gs/reflect/value.ts +50 -1
  446. package/gs/reflect/visiblefields.ts +1 -1
  447. package/gs/runtime/debug/index.test.ts +45 -0
  448. package/gs/runtime/debug/index.ts +96 -0
  449. package/gs/runtime/pprof/index.test.ts +36 -0
  450. package/gs/runtime/pprof/index.ts +104 -0
  451. package/gs/runtime/pprof/meta.json +6 -0
  452. package/gs/runtime/runtime.test.ts +19 -0
  453. package/gs/runtime/runtime.ts +98 -3
  454. package/gs/runtime/trace/index.test.ts +45 -0
  455. package/gs/runtime/trace/index.ts +97 -0
  456. package/gs/runtime/trace/meta.json +7 -0
  457. package/gs/slices/meta.json +2 -1
  458. package/gs/slices/slices.test.ts +180 -0
  459. package/gs/slices/slices.ts +502 -15
  460. package/gs/sort/meta.json +7 -0
  461. package/gs/sort/slice.gs.ts +85 -26
  462. package/gs/sort/slice.test.ts +40 -0
  463. package/gs/sort/sort.gs.ts +16 -13
  464. package/gs/strings/builder.test.ts +8 -0
  465. package/gs/strings/builder.ts +33 -20
  466. package/gs/strings/iter.test.ts +5 -7
  467. package/gs/strings/iter.ts +146 -71
  468. package/gs/strings/replace.test.ts +1 -4
  469. package/gs/strings/replace.ts +6 -6
  470. package/gs/strings/strings.test.ts +4 -0
  471. package/gs/strings/strings.ts +54 -6
  472. package/gs/sync/atomic/type.gs.ts +13 -14
  473. package/gs/sync/meta.json +3 -1
  474. package/gs/sync/sync.test.ts +69 -1
  475. package/gs/sync/sync.ts +72 -13
  476. package/gs/syscall/constants.ts +39 -24
  477. package/gs/syscall/errors.ts +165 -112
  478. package/gs/syscall/fs.ts +195 -0
  479. package/gs/syscall/js/index.ts +485 -0
  480. package/gs/syscall/js/meta.json +4 -0
  481. package/gs/syscall/net.test.ts +111 -0
  482. package/gs/syscall/types.ts +63 -2
  483. package/gs/testing/index.ts +1 -0
  484. package/gs/testing/meta.json +5 -0
  485. package/gs/testing/testing.test.ts +146 -0
  486. package/gs/testing/testing.ts +399 -0
  487. package/gs/time/meta.json +2 -2
  488. package/gs/time/time.test.ts +110 -0
  489. package/gs/time/time.ts +309 -57
  490. package/gs/unicode/unicode.test.ts +36 -0
  491. package/gs/unicode/unicode.ts +115 -9
  492. package/gs/unicode/utf8/utf8.test.ts +13 -0
  493. package/gs/unicode/utf8/utf8.ts +28 -16
  494. package/gs/unique/index.ts +98 -0
  495. package/package.json +3 -2
@@ -130,7 +130,7 @@ export function readIntBE(b: $.Bytes, size: uintptr): number {
130
130
  case 4:
131
131
  return (byteorder.BEUint32(b) as number)
132
132
  case 8:
133
- return (byteorder.BEUint64(b) as number)
133
+ return Number(byteorder.BEUint64(b))
134
134
  default:
135
135
  $.panic("syscall: readInt with unsupported size")
136
136
  return 0 // This line will never be reached due to panic, but satisfies TypeScript
@@ -146,10 +146,9 @@ export function readIntLE(b: $.Bytes, size: uintptr): number {
146
146
  case 4:
147
147
  return (byteorder.LEUint32(b) as number)
148
148
  case 8:
149
- return (byteorder.LEUint64(b) as number)
149
+ return Number(byteorder.LEUint64(b))
150
150
  default:
151
151
  $.panic("syscall: readInt with unsupported size")
152
152
  return 0 // This line will never be reached due to panic, but satisfies TypeScript
153
153
  }
154
154
  }
155
-
package/gs/os/error.gs.ts CHANGED
@@ -184,6 +184,9 @@ export function underlyingErrorIs(err: $.GoError, target: $.GoError): boolean {
184
184
  if (err == target) {
185
185
  return true
186
186
  }
187
+ if (err !== null && typeof (err as any).Is === "function") {
188
+ return (err as any).Is(target) === true
189
+ }
187
190
  // To preserve prior behavior, only examine syscall errors.
188
191
  let { value: e, ok: ok } = $.typeAssert<any>(err, 'syscallErrorType')
189
192
  return ok && e.Is(target)
@@ -191,15 +194,11 @@ export function underlyingErrorIs(err: $.GoError, target: $.GoError): boolean {
191
194
 
192
195
  // underlyingError returns the underlying error for known os error types.
193
196
  export function underlyingError(err: $.GoError): $.GoError {
194
- $.typeSwitch(err, [{ types: [{kind: $.TypeKind.Pointer, elemType: 'PathError'}], body: (err) => {
195
- return err!.Err
196
- }},
197
- { types: [{kind: $.TypeKind.Pointer, elemType: 'LinkError'}], body: (err) => {
198
- return err!.Err
199
- }},
200
- { types: [{kind: $.TypeKind.Pointer, elemType: 'SyscallError'}], body: (err) => {
201
- return err!.Err
202
- }}])
197
+ if (err !== null && typeof (err as any).Unwrap === "function") {
198
+ const unwrapped = (err as any).Unwrap()
199
+ if (unwrapped !== null && typeof unwrapped?.Error === "function") {
200
+ return unwrapped
201
+ }
202
+ }
203
203
  return err
204
204
  }
205
-
@@ -0,0 +1,41 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import {
4
+ ErrNotExist,
5
+ IsExist,
6
+ IsNotExist,
7
+ IsPermission,
8
+ PathError,
9
+ } from './error.gs.js'
10
+ import { newHostError } from './types_js.gs.js'
11
+
12
+ function hostError(code: string): Error {
13
+ return Object.assign(new Error(code), { code })
14
+ }
15
+
16
+ describe('os error classification', () => {
17
+ it('unwraps path errors before comparing sentinel errors', () => {
18
+ const err = new PathError({
19
+ Err: ErrNotExist,
20
+ Op: 'open',
21
+ Path: 'missing',
22
+ })
23
+
24
+ expect(IsNotExist(err)).toBe(true)
25
+ expect(IsExist(err)).toBe(false)
26
+ })
27
+
28
+ it('recognizes host filesystem error codes', () => {
29
+ expect(IsNotExist(newHostError(hostError('ENOENT')))).toBe(true)
30
+ expect(IsNotExist(newHostError(hostError('ENOTDIR')))).toBe(true)
31
+ expect(IsExist(newHostError(hostError('EEXIST')))).toBe(true)
32
+ expect(IsPermission(newHostError(hostError('EACCES')))).toBe(true)
33
+ expect(IsPermission(newHostError(hostError('EPERM')))).toBe(true)
34
+ })
35
+
36
+ it('does not treat unrelated host errors as filesystem sentinels', () => {
37
+ expect(IsNotExist(newHostError(hostError('EIO')))).toBe(false)
38
+ expect(IsExist(newHostError(hostError('EIO')))).toBe(false)
39
+ expect(IsPermission(newHostError(hostError('EIO')))).toBe(false)
40
+ })
41
+ })
@@ -231,4 +231,59 @@ describe('os stdio', () => {
231
231
  expect(handle.writeSync).toHaveBeenCalledTimes(2)
232
232
  expect(Array.from(handle.writeSync.mock.calls[1][0])).toEqual([22, 23])
233
233
  })
234
+
235
+ it('supports ReadAt and WriteAt on process fs descriptors', () => {
236
+ const readSync = vi.fn(
237
+ (
238
+ _fd: number,
239
+ buffer: Uint8Array,
240
+ offset?: number,
241
+ length?: number,
242
+ position?: number | null,
243
+ ) => {
244
+ expect(offset).toBe(0)
245
+ expect(length).toBe(3)
246
+ expect(position).toBe(5)
247
+ buffer.set([31, 32, 33], 0)
248
+ return 3
249
+ },
250
+ )
251
+ const writeSync = vi.fn(
252
+ (
253
+ _fd: number,
254
+ _buffer: Uint8Array,
255
+ offset?: number,
256
+ length?: number,
257
+ position?: number | null,
258
+ ) => {
259
+ expect(offset).toBe(0)
260
+ expect(length).toBe(2)
261
+ expect(position).toBe(8)
262
+ return length ?? 0
263
+ },
264
+ )
265
+
266
+ delete (globalThis as any).Deno
267
+ ;(globalThis as any).process = {
268
+ getBuiltinModule: vi.fn(() => ({
269
+ readSync,
270
+ writeSync,
271
+ })),
272
+ }
273
+ resetHostRuntimeForTests()
274
+
275
+ const file = createHostFile('descriptor-file', 7)
276
+ const buf = new Uint8Array(3)
277
+
278
+ const [readN, readErr] = file.ReadAt(buf, 5)
279
+ expect(readN).toBe(3)
280
+ expect(readErr).toBeNull()
281
+ expect(Array.from(buf)).toEqual([31, 32, 33])
282
+
283
+ const [writeN, writeErr] = file.WriteAt(new Uint8Array([41, 42]), 8)
284
+ expect(writeN).toBe(2)
285
+ expect(writeErr).toBeNull()
286
+ expect(readSync).toHaveBeenCalledTimes(1)
287
+ expect(writeSync).toHaveBeenCalledTimes(1)
288
+ })
234
289
  })
@@ -1,16 +1,29 @@
1
1
  import { basename, join } from 'node:path'
2
- import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
2
+ import {
3
+ existsSync,
4
+ mkdtempSync,
5
+ readFileSync,
6
+ rmSync,
7
+ writeFileSync,
8
+ } from 'node:fs'
3
9
  import { tmpdir } from 'node:os'
4
10
  import { afterEach, describe, expect, it, vi } from 'vitest'
5
11
 
6
12
  import { ErrUnimplemented } from './error.gs.js'
7
13
  import { CreateTemp, MkdirTemp } from './tempfile.gs.js'
14
+ import * as errors from '../errors/errors.js'
15
+ import { ErrNotExist } from './error.gs.js'
16
+ import { Stat } from './stat_js.gs.js'
8
17
 
9
18
  const tempRoots: string[] = []
19
+ const originalCrypto = globalThis.crypto
10
20
 
11
21
  afterEach(() => {
12
22
  vi.restoreAllMocks()
13
- vi.unstubAllGlobals()
23
+ Object.defineProperty(globalThis, 'crypto', {
24
+ configurable: true,
25
+ value: originalCrypto,
26
+ })
14
27
  for (const root of tempRoots.splice(0)) {
15
28
  rmSync(root, { force: true, recursive: true })
16
29
  }
@@ -23,13 +36,16 @@ function makeTempRoot(): string {
23
36
  }
24
37
 
25
38
  function stubRandomBytes(bytes: number[]): void {
26
- vi.stubGlobal('crypto', {
27
- getRandomValues: vi.fn((dst: Uint8Array) => {
28
- for (let i = 0; i < dst.length; i++) {
29
- dst[i] = bytes[i] ?? 0
30
- }
31
- return dst
32
- }),
39
+ Object.defineProperty(globalThis, 'crypto', {
40
+ configurable: true,
41
+ value: {
42
+ getRandomValues: vi.fn((dst: Uint8Array) => {
43
+ for (let i = 0; i < dst.length; i++) {
44
+ dst[i] = bytes[i] ?? 0
45
+ }
46
+ return dst
47
+ }),
48
+ },
33
49
  })
34
50
  }
35
51
 
@@ -74,7 +90,10 @@ describe('os temp files', () => {
74
90
 
75
91
  it('reports ErrUnimplemented without a secure random source', () => {
76
92
  const root = makeTempRoot()
77
- vi.stubGlobal('crypto', {})
93
+ Object.defineProperty(globalThis, 'crypto', {
94
+ configurable: true,
95
+ value: {},
96
+ })
78
97
  forbidMathRandom()
79
98
 
80
99
  const [dir, err] = MkdirTemp(root, 'dir-*')
@@ -82,4 +101,12 @@ describe('os temp files', () => {
82
101
  expect(dir).toBe('')
83
102
  expect(err).toBe(ErrUnimplemented)
84
103
  })
104
+
105
+ it('maps host missing-path errors to ErrNotExist', () => {
106
+ const root = makeTempRoot()
107
+
108
+ const [, err] = Stat(join(root, 'missing'))
109
+
110
+ expect(errors.Is(err, ErrNotExist)).toBe(true)
111
+ })
85
112
  })
@@ -29,7 +29,37 @@ export function newHostError(err: unknown): $.GoError {
29
29
  err instanceof Error ? err.message
30
30
  : typeof err === "string" ? err
31
31
  : String(err)
32
- return { Error: () => message }
32
+ const target = hostErrorTarget(err)
33
+ const hostErr: Exclude<$.GoError, null> = {
34
+ Error: () => message,
35
+ }
36
+ Object.defineProperty(hostErr, "Is", {
37
+ value: (candidate: $.GoError) => target !== null && candidate === target,
38
+ })
39
+ return hostErr
40
+ }
41
+
42
+ function hostErrorTarget(err: unknown): $.GoError {
43
+ const codeValue = typeof err === "object" && err !== null && "code" in err
44
+ ? Reflect.get(err, "code")
45
+ : ""
46
+ const code = codeValue === undefined ? "" : String(codeValue)
47
+ switch (code) {
48
+ case "ENOENT":
49
+ case "ENOTDIR":
50
+ return fs.ErrNotExist
51
+ case "EEXIST":
52
+ return fs.ErrExist
53
+ case "EACCES":
54
+ case "EPERM":
55
+ return fs.ErrPermission
56
+ case "EBADF":
57
+ return ErrClosed
58
+ case "EINVAL":
59
+ return ErrInvalid
60
+ default:
61
+ return null
62
+ }
33
63
  }
34
64
 
35
65
  export function getNodeFS(): NodeFSModule | null {
@@ -296,23 +326,51 @@ export class File {
296
326
  }
297
327
 
298
328
  public ReadAt(b: $.Bytes, off: number): [number, $.GoError] {
329
+ if (this.closed) {
330
+ return [0, ErrClosed]
331
+ }
332
+ if (off < 0) {
333
+ return [0, ErrInvalid]
334
+ }
335
+ if (b === null) {
336
+ return [0, null]
337
+ }
338
+ const buf = $.bytesToUint8Array(b)
299
339
  const handle = this.file?.handle
300
- if (!handle || typeof handle.seekSync !== "function" || b === null) {
301
- return [0, ErrUnimplemented]
340
+ if (handle && typeof handle.seekSync === "function") {
341
+ try {
342
+ handle.seekSync(off, io.SeekStart)
343
+ return this.Read(b)
344
+ } catch (err) {
345
+ return [0, newHostError(err)]
346
+ }
302
347
  }
303
- try {
304
- handle.seekSync(off, io.SeekStart)
305
- return this.Read(b)
306
- } catch (err) {
307
- return [0, newHostError(err)]
348
+ if (this.fd < 0) {
349
+ return [0, ErrInvalid]
350
+ }
351
+ const nodeFS = getNodeFS()
352
+ if (nodeFS?.readSync && this.fd >= 0) {
353
+ try {
354
+ const n = nodeFS.readSync(this.fd, buf, 0, buf.length, off)
355
+ if (!(b instanceof Uint8Array) && n > 0) {
356
+ $.copy(b, buf.subarray(0, n))
357
+ }
358
+ if (n === 0) {
359
+ return [0, io.EOF]
360
+ }
361
+ return [n, null]
362
+ } catch (err) {
363
+ return [0, newHostError(err)]
364
+ }
308
365
  }
366
+ return [0, ErrUnimplemented]
309
367
  }
310
368
 
311
369
  public ReadFrom(r: io.Reader): [number, $.GoError] {
312
370
  if (this.closed) {
313
371
  return [0, ErrClosed]
314
372
  }
315
- return io.Copy(this, r)
373
+ return io.Copy(this, r) as any
316
374
  }
317
375
 
318
376
  public Write(b: $.Bytes): [number, $.GoError] {
@@ -333,23 +391,44 @@ export class File {
333
391
  }
334
392
 
335
393
  public WriteAt(b: $.Bytes, off: number): [number, $.GoError] {
394
+ if (this.closed) {
395
+ return [0, ErrClosed]
396
+ }
397
+ if (off < 0) {
398
+ return [0, ErrInvalid]
399
+ }
400
+ if (b === null) {
401
+ return [0, null]
402
+ }
403
+ const buf = $.bytesToUint8Array(b)
336
404
  const handle = this.file?.handle
337
- if (!handle || typeof handle.seekSync !== "function" || b === null) {
338
- return [0, ErrUnimplemented]
405
+ if (handle && typeof handle.seekSync === "function") {
406
+ try {
407
+ handle.seekSync(off, io.SeekStart)
408
+ return this.Write(b)
409
+ } catch (err) {
410
+ return [0, newHostError(err)]
411
+ }
339
412
  }
340
- try {
341
- handle.seekSync(off, io.SeekStart)
342
- return this.Write(b)
343
- } catch (err) {
344
- return [0, newHostError(err)]
413
+ if (this.fd < 0) {
414
+ return [0, ErrInvalid]
345
415
  }
416
+ const nodeFS = getNodeFS()
417
+ if (nodeFS?.writeSync && this.fd >= 0) {
418
+ try {
419
+ return [nodeFS.writeSync(this.fd, buf, 0, buf.length, off), null]
420
+ } catch (err) {
421
+ return [0, newHostError(err)]
422
+ }
423
+ }
424
+ return [0, ErrUnimplemented]
346
425
  }
347
426
 
348
427
  public WriteTo(w: io.Writer): [number, $.GoError] {
349
428
  if (this.closed) {
350
429
  return [0, ErrClosed]
351
430
  }
352
- return io.Copy(w, this)
431
+ return io.Copy(w, this) as any
353
432
  }
354
433
 
355
434
  public Seek(offset: number, whence: number): [number, $.GoError] {
@@ -1,4 +1,7 @@
1
1
  import { describe, it, expect } from 'vitest'
2
+ import { mkdirSync, mkdtempSync, rmSync } from 'node:fs'
3
+ import { tmpdir } from 'node:os'
4
+ import { join } from 'node:path'
2
5
  import { Match, Glob, ErrBadPattern } from './match.js'
3
6
 
4
7
  describe('path/filepath - Pattern matching functions', () => {
@@ -216,20 +219,36 @@ describe('path/filepath - Pattern matching functions', () => {
216
219
  })
217
220
 
218
221
  describe('Glob', () => {
219
- it('should validate patterns but return empty results (no filesystem)', () => {
220
- // Valid patterns should not error
221
- const [files1, err1] = Glob('*.txt')
222
- expect(err1).toBeNull()
223
- expect(files1).toEqual([])
222
+ it('should read host filesystem matches', () => {
223
+ const root = mkdtempSync(join(tmpdir(), 'goscript-filepath-glob-'))
224
+ const oldwd = process.cwd()
225
+ try {
226
+ mkdirSync(join(root, 'a', 'b', 'c.d', 'e.f'), { recursive: true })
227
+ process.chdir(root)
228
+
229
+ const [files1, err1] = Glob('./*/*/*.d')
230
+ expect(err1).toBeNull()
231
+ expect(files1).toEqual(['a/b/c.d'])
224
232
 
225
- const [files2, err2] = Glob('dir/*')
226
- expect(err2).toBeNull()
227
- expect(files2).toEqual([])
233
+ const [files2, err2] = Glob('a/b/c.d/e.*')
234
+ expect(err2).toBeNull()
235
+ expect(files2).toEqual(['a/b/c.d/e.f'])
236
+ } finally {
237
+ process.chdir(oldwd)
238
+ rmSync(root, { force: true, recursive: true })
239
+ }
240
+ })
228
241
 
229
- // Invalid patterns should error
230
- const [files3, err3] = Glob('[unclosed')
231
- expect(err3).toBe(ErrBadPattern)
232
- expect(files3).toEqual([])
242
+ it('should validate bad patterns', () => {
243
+ const [files1, err1] = Glob('[unclosed')
244
+ expect(err1).toBe(ErrBadPattern)
245
+ expect(files1).toEqual([])
246
+ })
247
+
248
+ it('should return empty results for unmatched valid patterns', () => {
249
+ const [files1, err1] = Glob('missing-*.txt')
250
+ expect(err1).toBeNull()
251
+ expect(files1).toEqual([])
233
252
  })
234
253
  })
235
254
 
@@ -1,4 +1,5 @@
1
1
  import * as $ from '@goscript/builtin/index.js'
2
+ import { getHostRuntime, type NodeFSModule } from '@goscript/builtin/hostio.js'
2
3
 
3
4
  export const ErrBadPattern = $.newError('syntax error in pattern')
4
5
 
@@ -238,12 +239,189 @@ function matchCharClass(
238
239
  // The only possible returned error is ErrBadPattern, when pattern is malformed.
239
240
  export function Glob(pattern: string): [string[], $.GoError] {
240
241
  try {
241
- // Validate the pattern using the same logic as Match
242
242
  validatePattern(pattern)
243
- // We don't have filesystem access, so return empty array
244
- return [[], null]
243
+ return [globHost(pattern), null]
245
244
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
246
245
  } catch (err) {
247
246
  return [[], ErrBadPattern]
248
247
  }
249
248
  }
249
+
250
+ function hasMeta(path: string): boolean {
251
+ return /[*?[\\]/.test(path)
252
+ }
253
+
254
+ function splitPattern(pattern: string): {
255
+ absolute: boolean
256
+ segments: string[]
257
+ } {
258
+ const absolute = pattern.startsWith('/')
259
+ const segments = pattern.split('/').filter((segment, index) => {
260
+ if (index === 0 && segment === '') {
261
+ return false
262
+ }
263
+ return segment !== '' && segment !== '.'
264
+ })
265
+ return { absolute, segments }
266
+ }
267
+
268
+ function cleanMatch(path: string): string {
269
+ const absolute = path.startsWith('/')
270
+ const parts: string[] = []
271
+ for (const part of path.split('/')) {
272
+ if (part === '' || part === '.') {
273
+ continue
274
+ }
275
+ if (part === '..') {
276
+ if (parts.length > 0 && parts[parts.length - 1] !== '..') {
277
+ parts.pop()
278
+ } else if (!absolute) {
279
+ parts.push(part)
280
+ }
281
+ continue
282
+ }
283
+ parts.push(part)
284
+ }
285
+ const out = parts.join('/')
286
+ if (absolute) {
287
+ return '/' + out
288
+ }
289
+ return out === '' ? '.' : out
290
+ }
291
+
292
+ function joinPath(dir: string, name: string): string {
293
+ if (dir === '' || dir === '.') {
294
+ return name
295
+ }
296
+ if (dir === '/') {
297
+ return '/' + name
298
+ }
299
+ return dir.replace(/\/+$/, '') + '/' + name
300
+ }
301
+
302
+ type HostDirEntry = { name: string; isDir: boolean }
303
+
304
+ function readDir(path: string): HostDirEntry[] | null {
305
+ const runtime = getHostRuntime()
306
+ const denoObj = runtime.deno
307
+ if (denoObj?.readDirSync) {
308
+ try {
309
+ const entries: HostDirEntry[] = []
310
+ for (const entry of denoObj.readDirSync(path)) {
311
+ entries.push({ name: entry.name, isDir: !!entry.isDirectory })
312
+ }
313
+ entries.sort((a, b) => a.name.localeCompare(b.name))
314
+ return entries
315
+ } catch {
316
+ return null
317
+ }
318
+ }
319
+
320
+ const nodeFS = runtime.nodeFS
321
+ if (nodeFS?.readdirSync) {
322
+ try {
323
+ const entries = nodeFS
324
+ .readdirSync(path, { withFileTypes: true })
325
+ .map((entry: any) => ({
326
+ name: String(entry.name),
327
+ isDir:
328
+ typeof entry.isDirectory === 'function' ?
329
+ entry.isDirectory()
330
+ : false,
331
+ }))
332
+ entries.sort((a, b) => a.name.localeCompare(b.name))
333
+ return entries
334
+ } catch {
335
+ return null
336
+ }
337
+ }
338
+
339
+ return null
340
+ }
341
+
342
+ function exists(path: string): boolean {
343
+ const runtime = getHostRuntime()
344
+ if (runtime.deno?.statSync) {
345
+ try {
346
+ runtime.deno.statSync(path)
347
+ return true
348
+ } catch {
349
+ return false
350
+ }
351
+ }
352
+
353
+ const nodeFS = runtime.nodeFS
354
+ if (nodeFS?.statSync) {
355
+ try {
356
+ nodeFS.statSync(path)
357
+ return true
358
+ } catch {
359
+ return false
360
+ }
361
+ }
362
+
363
+ return false
364
+ }
365
+
366
+ function isDir(path: string, nodeFS?: NodeFSModule | null): boolean {
367
+ const runtime = getHostRuntime()
368
+ if (runtime.deno?.statSync) {
369
+ try {
370
+ return !!runtime.deno.statSync(path).isDirectory
371
+ } catch {
372
+ return false
373
+ }
374
+ }
375
+
376
+ const fs = nodeFS ?? runtime.nodeFS
377
+ if (fs?.statSync) {
378
+ try {
379
+ const stat = fs.statSync(path)
380
+ return typeof stat.isDirectory === 'function' ? stat.isDirectory() : false
381
+ } catch {
382
+ return false
383
+ }
384
+ }
385
+
386
+ return false
387
+ }
388
+
389
+ function globHost(pattern: string): string[] {
390
+ const { absolute, segments } = splitPattern(pattern)
391
+ if (!hasMeta(pattern)) {
392
+ return exists(pattern) ? [cleanMatch(pattern)] : []
393
+ }
394
+
395
+ let prefixes = [absolute ? '/' : '.']
396
+ for (const [index, segment] of segments.entries()) {
397
+ const next: string[] = []
398
+ const last = index === segments.length - 1
399
+ const segmentHasMeta = hasMeta(segment)
400
+ for (const prefix of prefixes) {
401
+ if (!segmentHasMeta) {
402
+ const candidate = joinPath(prefix, segment)
403
+ if (last || isDir(candidate)) {
404
+ next.push(candidate)
405
+ }
406
+ continue
407
+ }
408
+
409
+ const entries = readDir(prefix)
410
+ if (entries === null) {
411
+ continue
412
+ }
413
+ for (const entry of entries) {
414
+ const [matched, err] = Match(segment, entry.name)
415
+ if (err !== null || !matched) {
416
+ continue
417
+ }
418
+ if (last || entry.isDir) {
419
+ next.push(joinPath(prefix, entry.name))
420
+ }
421
+ }
422
+ }
423
+ prefixes = next
424
+ }
425
+
426
+ return prefixes.map(cleanMatch).sort()
427
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "asyncFunctions": {
3
+ "Walk": true,
4
+ "WalkDir": true
5
+ }
6
+ }