goscript 0.1.1 → 0.1.3

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 (376) hide show
  1. package/cmd/goscript/cmd-test.go +104 -11
  2. package/cmd/goscript/cmd-test_test.go +1 -1
  3. package/cmd/goscript/cmd_compile.go +9 -0
  4. package/compiler/compile-request.go +31 -0
  5. package/compiler/compiler.go +1 -1
  6. package/compiler/compliance_test.go +0 -2
  7. package/compiler/config.go +2 -0
  8. package/compiler/gotest/package-result.go +2 -0
  9. package/compiler/gotest/request.go +85 -20
  10. package/compiler/gotest/runner.go +733 -96
  11. package/compiler/gotest/runner_test.go +647 -3
  12. package/compiler/lowered-program.go +10 -2
  13. package/compiler/lowering.go +2676 -349
  14. package/compiler/override-facts.go +77 -27
  15. package/compiler/override-registry.go +5 -4
  16. package/compiler/override-registry_test.go +178 -0
  17. package/compiler/package-graph_test.go +62 -7
  18. package/compiler/package-test-graph-variant.go +40 -16
  19. package/compiler/package-test-graph.go +0 -5
  20. package/compiler/package-test-graph_test.go +61 -3
  21. package/compiler/runtime-contract.go +40 -0
  22. package/compiler/semantic-model-types.go +16 -0
  23. package/compiler/semantic-model.go +336 -91
  24. package/compiler/semantic-model_test.go +50 -1
  25. package/compiler/service.go +9 -3
  26. package/compiler/skeleton_test.go +2371 -296
  27. package/compiler/tsworkspace/owner-process-unix_test.go +72 -0
  28. package/compiler/tsworkspace/owner.go +8 -0
  29. package/compiler/tsworkspace/tool-process-other.go +14 -0
  30. package/compiler/tsworkspace/tool-process-unix.go +19 -0
  31. package/compiler/typescript-emitter.go +149 -10
  32. package/dist/gs/builtin/builtin.d.ts +20 -1
  33. package/dist/gs/builtin/builtin.js +246 -26
  34. package/dist/gs/builtin/builtin.js.map +1 -1
  35. package/dist/gs/builtin/channel.d.ts +24 -10
  36. package/dist/gs/builtin/channel.js +143 -34
  37. package/dist/gs/builtin/channel.js.map +1 -1
  38. package/dist/gs/builtin/defer.d.ts +1 -0
  39. package/dist/gs/builtin/defer.js +12 -2
  40. package/dist/gs/builtin/defer.js.map +1 -1
  41. package/dist/gs/builtin/hostio.d.ts +9 -0
  42. package/dist/gs/builtin/hostio.js +25 -0
  43. package/dist/gs/builtin/hostio.js.map +1 -1
  44. package/dist/gs/builtin/map.js +40 -6
  45. package/dist/gs/builtin/map.js.map +1 -1
  46. package/dist/gs/builtin/print.js.map +1 -1
  47. package/dist/gs/builtin/slice.d.ts +43 -9
  48. package/dist/gs/builtin/slice.js +437 -234
  49. package/dist/gs/builtin/slice.js.map +1 -1
  50. package/dist/gs/builtin/type.d.ts +2 -0
  51. package/dist/gs/builtin/type.js +55 -10
  52. package/dist/gs/builtin/type.js.map +1 -1
  53. package/dist/gs/builtin/varRef.d.ts +2 -0
  54. package/dist/gs/builtin/varRef.js.map +1 -1
  55. package/dist/gs/bytes/buffer.gs.js +28 -28
  56. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  57. package/dist/gs/bytes/bytes.gs.d.ts +7 -5
  58. package/dist/gs/bytes/bytes.gs.js +10 -4
  59. package/dist/gs/bytes/bytes.gs.js.map +1 -1
  60. package/dist/gs/bytes/iter.gs.js +13 -13
  61. package/dist/gs/bytes/iter.gs.js.map +1 -1
  62. package/dist/gs/compress/zlib/index.d.ts +26 -0
  63. package/dist/gs/compress/zlib/index.js +168 -0
  64. package/dist/gs/compress/zlib/index.js.map +1 -0
  65. package/dist/gs/context/context.d.ts +1 -1
  66. package/dist/gs/context/context.js +8 -3
  67. package/dist/gs/context/context.js.map +1 -1
  68. package/dist/gs/crypto/ecdh/index.d.ts +52 -0
  69. package/dist/gs/crypto/ecdh/index.js +226 -0
  70. package/dist/gs/crypto/ecdh/index.js.map +1 -0
  71. package/dist/gs/crypto/ed25519/index.d.ts +34 -0
  72. package/dist/gs/crypto/ed25519/index.js +160 -0
  73. package/dist/gs/crypto/ed25519/index.js.map +1 -0
  74. package/dist/gs/crypto/internal/constanttime/index.d.ts +4 -0
  75. package/dist/gs/crypto/internal/constanttime/index.js +18 -0
  76. package/dist/gs/crypto/internal/constanttime/index.js.map +1 -0
  77. package/dist/gs/crypto/rand/index.d.ts +2 -0
  78. package/dist/gs/crypto/rand/index.js +85 -0
  79. package/dist/gs/crypto/rand/index.js.map +1 -1
  80. package/dist/gs/crypto/sha1/index.d.ts +5 -0
  81. package/dist/gs/crypto/sha1/index.js +106 -0
  82. package/dist/gs/crypto/sha1/index.js.map +1 -0
  83. package/dist/gs/crypto/sha256/index.d.ts +8 -0
  84. package/dist/gs/crypto/sha256/index.js +118 -0
  85. package/dist/gs/crypto/sha256/index.js.map +1 -0
  86. package/dist/gs/crypto/sha512/index.d.ts +14 -0
  87. package/dist/gs/crypto/sha512/index.js +129 -0
  88. package/dist/gs/crypto/sha512/index.js.map +1 -0
  89. package/dist/gs/encoding/json/index.d.ts +3 -0
  90. package/dist/gs/encoding/json/index.js +15 -0
  91. package/dist/gs/encoding/json/index.js.map +1 -1
  92. package/dist/gs/errors/errors.js +29 -6
  93. package/dist/gs/errors/errors.js.map +1 -1
  94. package/dist/gs/fmt/fmt.d.ts +1 -1
  95. package/dist/gs/fmt/fmt.js +64 -3
  96. package/dist/gs/fmt/fmt.js.map +1 -1
  97. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +7 -7
  98. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +52 -18
  99. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  100. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +56 -20
  101. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -1
  102. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +57 -3
  103. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +366 -1
  104. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -1
  105. package/dist/gs/github.com/aperturerobotics/util/conc/index.d.ts +20 -0
  106. package/dist/gs/github.com/aperturerobotics/util/conc/index.js +134 -0
  107. package/dist/gs/github.com/aperturerobotics/util/conc/index.js.map +1 -0
  108. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
  109. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.d.ts +3 -0
  110. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js +50 -0
  111. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js.map +1 -0
  112. package/dist/gs/github.com/klauspost/compress/internal/le/index.js +3 -2
  113. package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -1
  114. package/dist/gs/github.com/mr-tron/base58/base58/index.d.ts +27 -0
  115. package/dist/gs/github.com/mr-tron/base58/base58/index.js +172 -0
  116. package/dist/gs/github.com/mr-tron/base58/base58/index.js.map +1 -0
  117. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.d.ts +21 -0
  118. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js +22 -0
  119. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js.map +1 -0
  120. package/dist/gs/go/token/index.js +11 -4
  121. package/dist/gs/go/token/index.js.map +1 -1
  122. package/dist/gs/hash/fnv/index.d.ts +57 -0
  123. package/dist/gs/hash/fnv/index.js +299 -0
  124. package/dist/gs/hash/fnv/index.js.map +1 -0
  125. package/dist/gs/hash/index.d.ts +17 -0
  126. package/dist/gs/hash/index.js +94 -0
  127. package/dist/gs/hash/index.js.map +1 -0
  128. package/dist/gs/io/fs/readlink.js +2 -6
  129. package/dist/gs/io/fs/readlink.js.map +1 -1
  130. package/dist/gs/io/fs/walk.js.map +1 -1
  131. package/dist/gs/io/io.d.ts +8 -5
  132. package/dist/gs/io/io.js +20 -2
  133. package/dist/gs/io/io.js.map +1 -1
  134. package/dist/gs/iter/iter.d.ts +3 -2
  135. package/dist/gs/iter/iter.js.map +1 -1
  136. package/dist/gs/maps/iter.d.ts +5 -5
  137. package/dist/gs/maps/iter.js +48 -21
  138. package/dist/gs/maps/iter.js.map +1 -1
  139. package/dist/gs/maps/maps.d.ts +6 -6
  140. package/dist/gs/math/bits/index.js +14 -24
  141. package/dist/gs/math/bits/index.js.map +1 -1
  142. package/dist/gs/mime/index.js +3 -1
  143. package/dist/gs/mime/index.js.map +1 -1
  144. package/dist/gs/net/http/httptest/index.d.ts +20 -1
  145. package/dist/gs/net/http/httptest/index.js +85 -3
  146. package/dist/gs/net/http/httptest/index.js.map +1 -1
  147. package/dist/gs/net/http/index.d.ts +118 -6
  148. package/dist/gs/net/http/index.js +389 -14
  149. package/dist/gs/net/http/index.js.map +1 -1
  150. package/dist/gs/net/http/pprof/index.d.ts +8 -0
  151. package/dist/gs/net/http/pprof/index.js +59 -0
  152. package/dist/gs/net/http/pprof/index.js.map +1 -0
  153. package/dist/gs/os/error.gs.js +9 -7
  154. package/dist/gs/os/error.gs.js.map +1 -1
  155. package/dist/gs/os/types_js.gs.js +95 -15
  156. package/dist/gs/os/types_js.gs.js.map +1 -1
  157. package/dist/gs/os/zero_copy_posix.gs.js +1 -1
  158. package/dist/gs/os/zero_copy_posix.gs.js.map +1 -1
  159. package/dist/gs/path/filepath/match.js.map +1 -1
  160. package/dist/gs/path/filepath/path.d.ts +5 -3
  161. package/dist/gs/path/filepath/path.js +65 -10
  162. package/dist/gs/path/filepath/path.js.map +1 -1
  163. package/dist/gs/reflect/index.d.ts +3 -2
  164. package/dist/gs/reflect/index.js +2 -1
  165. package/dist/gs/reflect/index.js.map +1 -1
  166. package/dist/gs/reflect/iter.js +2 -2
  167. package/dist/gs/reflect/iter.js.map +1 -1
  168. package/dist/gs/reflect/map.js +26 -0
  169. package/dist/gs/reflect/map.js.map +1 -1
  170. package/dist/gs/reflect/type.d.ts +24 -5
  171. package/dist/gs/reflect/type.js +390 -38
  172. package/dist/gs/reflect/type.js.map +1 -1
  173. package/dist/gs/reflect/types.d.ts +1 -0
  174. package/dist/gs/reflect/types.js +3 -1
  175. package/dist/gs/reflect/types.js.map +1 -1
  176. package/dist/gs/reflect/value.d.ts +4 -1
  177. package/dist/gs/reflect/value.js +39 -1
  178. package/dist/gs/reflect/value.js.map +1 -1
  179. package/dist/gs/reflect/visiblefields.js +1 -1
  180. package/dist/gs/reflect/visiblefields.js.map +1 -1
  181. package/dist/gs/runtime/debug/index.d.ts +39 -0
  182. package/dist/gs/runtime/debug/index.js +58 -0
  183. package/dist/gs/runtime/debug/index.js.map +1 -1
  184. package/dist/gs/runtime/pprof/index.d.ts +20 -0
  185. package/dist/gs/runtime/pprof/index.js +85 -0
  186. package/dist/gs/runtime/pprof/index.js.map +1 -0
  187. package/dist/gs/runtime/trace/index.d.ts +19 -0
  188. package/dist/gs/runtime/trace/index.js +64 -0
  189. package/dist/gs/runtime/trace/index.js.map +1 -0
  190. package/dist/gs/slices/slices.d.ts +24 -9
  191. package/dist/gs/slices/slices.js +229 -24
  192. package/dist/gs/slices/slices.js.map +1 -1
  193. package/dist/gs/sort/slice.gs.d.ts +5 -3
  194. package/dist/gs/sort/slice.gs.js +55 -17
  195. package/dist/gs/sort/slice.gs.js.map +1 -1
  196. package/dist/gs/strings/builder.js +26 -17
  197. package/dist/gs/strings/builder.js.map +1 -1
  198. package/dist/gs/strings/iter.js +140 -75
  199. package/dist/gs/strings/iter.js.map +1 -1
  200. package/dist/gs/strings/replace.js +2 -2
  201. package/dist/gs/strings/replace.js.map +1 -1
  202. package/dist/gs/strings/strings.js +52 -6
  203. package/dist/gs/strings/strings.js.map +1 -1
  204. package/dist/gs/sync/sync.d.ts +6 -3
  205. package/dist/gs/sync/sync.js +39 -11
  206. package/dist/gs/sync/sync.js.map +1 -1
  207. package/dist/gs/syscall/errors.d.ts +116 -112
  208. package/dist/gs/syscall/errors.js +38 -1
  209. package/dist/gs/syscall/errors.js.map +1 -1
  210. package/dist/gs/syscall/fs.d.ts +2 -8
  211. package/dist/gs/syscall/fs.js.map +1 -1
  212. package/dist/gs/syscall/js/index.js +20 -12
  213. package/dist/gs/syscall/js/index.js.map +1 -1
  214. package/dist/gs/syscall/types.d.ts +4 -1
  215. package/dist/gs/syscall/types.js.map +1 -1
  216. package/dist/gs/testing/testing.d.ts +4 -3
  217. package/dist/gs/testing/testing.js +21 -4
  218. package/dist/gs/testing/testing.js.map +1 -1
  219. package/dist/gs/time/time.js +22 -0
  220. package/dist/gs/time/time.js.map +1 -1
  221. package/dist/gs/unicode/unicode.js.map +1 -1
  222. package/dist/gs/unique/index.js +7 -2
  223. package/dist/gs/unique/index.js.map +1 -1
  224. package/go.mod +8 -8
  225. package/go.sum +14 -23
  226. package/gs/builtin/builtin.ts +364 -37
  227. package/gs/builtin/channel.ts +208 -38
  228. package/gs/builtin/defer.ts +13 -2
  229. package/gs/builtin/hostio.test.ts +1 -0
  230. package/gs/builtin/hostio.ts +38 -0
  231. package/gs/builtin/map.ts +46 -6
  232. package/gs/builtin/print.ts +12 -3
  233. package/gs/builtin/runtime-contract.test.ts +290 -10
  234. package/gs/builtin/slice.test.ts +70 -0
  235. package/gs/builtin/slice.ts +566 -255
  236. package/gs/builtin/type.ts +63 -10
  237. package/gs/builtin/varRef.ts +2 -0
  238. package/gs/bytes/buffer.gs.ts +28 -28
  239. package/gs/bytes/bytes.gs.ts +19 -10
  240. package/gs/bytes/bytes.test.ts +17 -0
  241. package/gs/bytes/iter.gs.ts +13 -14
  242. package/gs/compress/zlib/index.test.ts +28 -0
  243. package/gs/compress/zlib/index.ts +200 -0
  244. package/gs/compress/zlib/meta.json +3 -0
  245. package/gs/context/context.test.ts +36 -2
  246. package/gs/context/context.ts +9 -4
  247. package/gs/crypto/ecdh/index.test.ts +43 -0
  248. package/gs/crypto/ecdh/index.ts +274 -0
  249. package/gs/crypto/ed25519/index.test.ts +41 -0
  250. package/gs/crypto/ed25519/index.ts +238 -0
  251. package/gs/crypto/ed25519/meta.json +13 -0
  252. package/gs/crypto/internal/constanttime/index.test.ts +25 -0
  253. package/gs/crypto/internal/constanttime/index.ts +22 -0
  254. package/gs/crypto/rand/index.test.ts +89 -1
  255. package/gs/crypto/rand/index.ts +103 -1
  256. package/gs/crypto/rand/meta.json +4 -1
  257. package/gs/crypto/sha1/index.test.ts +28 -0
  258. package/gs/crypto/sha1/index.ts +130 -0
  259. package/gs/crypto/sha1/meta.json +8 -0
  260. package/gs/crypto/sha256/index.test.ts +78 -0
  261. package/gs/crypto/sha256/index.ts +150 -0
  262. package/gs/crypto/sha256/meta.json +9 -0
  263. package/gs/crypto/sha512/index.test.ts +31 -0
  264. package/gs/crypto/sha512/index.ts +161 -0
  265. package/gs/crypto/sha512/meta.json +11 -0
  266. package/gs/encoding/json/index.test.ts +25 -3
  267. package/gs/encoding/json/index.ts +21 -3
  268. package/gs/errors/errors.test.ts +4 -1
  269. package/gs/errors/errors.ts +32 -8
  270. package/gs/fmt/fmt.test.ts +23 -1
  271. package/gs/fmt/fmt.ts +76 -10
  272. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +62 -7
  273. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +78 -36
  274. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +32 -11
  275. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +122 -43
  276. package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +31 -0
  277. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +518 -4
  278. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +6 -0
  279. package/gs/github.com/aperturerobotics/util/conc/index.test.ts +30 -0
  280. package/gs/github.com/aperturerobotics/util/conc/index.ts +172 -0
  281. package/gs/github.com/aperturerobotics/util/conc/meta.json +9 -0
  282. package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.ts +1 -4
  283. package/gs/github.com/hack-pad/safejs/internal/catch/index.test.ts +35 -0
  284. package/gs/github.com/hack-pad/safejs/internal/catch/index.ts +65 -0
  285. package/gs/github.com/hack-pad/safejs/internal/catch/meta.json +9 -0
  286. package/gs/github.com/klauspost/compress/internal/le/index.test.ts +2 -1
  287. package/gs/github.com/klauspost/compress/internal/le/index.ts +6 -5
  288. package/gs/github.com/mr-tron/base58/base58/index.test.ts +70 -0
  289. package/gs/github.com/mr-tron/base58/base58/index.ts +231 -0
  290. package/gs/github.com/mr-tron/base58/base58/meta.json +3 -0
  291. package/gs/github.com/zeebo/blake3/internal/consts/index.test.ts +46 -0
  292. package/gs/github.com/zeebo/blake3/internal/consts/index.ts +26 -0
  293. package/gs/go/token/index.ts +17 -4
  294. package/gs/hash/fnv/index.test.ts +67 -0
  295. package/gs/hash/fnv/index.ts +351 -0
  296. package/gs/hash/fnv/meta.json +3 -0
  297. package/gs/hash/index.test.ts +37 -0
  298. package/gs/hash/index.ts +118 -0
  299. package/gs/hash/meta.json +5 -0
  300. package/gs/internal/byteorder/index.test.ts +6 -6
  301. package/gs/io/fs/readlink.ts +40 -48
  302. package/gs/io/fs/walk.ts +10 -2
  303. package/gs/io/io.test.ts +64 -0
  304. package/gs/io/io.ts +34 -13
  305. package/gs/iter/iter.ts +8 -2
  306. package/gs/maps/iter.ts +69 -26
  307. package/gs/maps/maps.test.ts +23 -0
  308. package/gs/maps/maps.ts +6 -6
  309. package/gs/math/bits/index.test.ts +20 -0
  310. package/gs/math/bits/index.ts +15 -28
  311. package/gs/mime/index.ts +8 -2
  312. package/gs/net/http/httptest/index.test.ts +85 -0
  313. package/gs/net/http/httptest/index.ts +113 -3
  314. package/gs/net/http/index.test.ts +159 -1
  315. package/gs/net/http/index.ts +515 -15
  316. package/gs/net/http/meta.json +6 -0
  317. package/gs/net/http/pprof/index.test.ts +47 -0
  318. package/gs/net/http/pprof/index.ts +65 -0
  319. package/gs/os/error.gs.ts +9 -10
  320. package/gs/os/error.test.ts +41 -0
  321. package/gs/os/file_unix_js.test.ts +55 -0
  322. package/gs/os/tempfile.gs.test.ts +37 -10
  323. package/gs/os/types_js.gs.ts +94 -15
  324. package/gs/os/zero_copy_posix.gs.ts +1 -2
  325. package/gs/path/filepath/match.ts +4 -1
  326. package/gs/path/filepath/meta.json +6 -0
  327. package/gs/path/filepath/path.test.ts +57 -2
  328. package/gs/path/filepath/path.ts +91 -12
  329. package/gs/reflect/field.test.ts +63 -0
  330. package/gs/reflect/index.ts +4 -1
  331. package/gs/reflect/iter.ts +2 -2
  332. package/gs/reflect/map.test.ts +24 -2
  333. package/gs/reflect/map.ts +35 -0
  334. package/gs/reflect/type.ts +543 -60
  335. package/gs/reflect/typefor.test.ts +100 -0
  336. package/gs/reflect/types.ts +3 -1
  337. package/gs/reflect/value.ts +50 -1
  338. package/gs/reflect/visiblefields.ts +1 -1
  339. package/gs/runtime/debug/index.test.ts +22 -1
  340. package/gs/runtime/debug/index.ts +88 -0
  341. package/gs/runtime/pprof/index.test.ts +36 -0
  342. package/gs/runtime/pprof/index.ts +104 -0
  343. package/gs/runtime/pprof/meta.json +6 -0
  344. package/gs/runtime/trace/index.test.ts +45 -0
  345. package/gs/runtime/trace/index.ts +97 -0
  346. package/gs/runtime/trace/meta.json +7 -0
  347. package/gs/slices/meta.json +2 -1
  348. package/gs/slices/slices.test.ts +86 -0
  349. package/gs/slices/slices.ts +284 -37
  350. package/gs/sort/slice.gs.ts +73 -23
  351. package/gs/sort/slice.test.ts +40 -0
  352. package/gs/strings/builder.test.ts +8 -0
  353. package/gs/strings/builder.ts +29 -17
  354. package/gs/strings/iter.test.ts +5 -7
  355. package/gs/strings/iter.ts +146 -71
  356. package/gs/strings/replace.test.ts +1 -4
  357. package/gs/strings/replace.ts +6 -6
  358. package/gs/strings/strings.test.ts +4 -0
  359. package/gs/strings/strings.ts +54 -6
  360. package/gs/sync/meta.json +1 -0
  361. package/gs/sync/sync.test.ts +57 -1
  362. package/gs/sync/sync.ts +45 -13
  363. package/gs/syscall/errors.ts +158 -115
  364. package/gs/syscall/fs.ts +8 -8
  365. package/gs/syscall/js/index.ts +49 -22
  366. package/gs/syscall/net.test.ts +26 -0
  367. package/gs/syscall/types.ts +7 -2
  368. package/gs/testing/testing.test.ts +56 -0
  369. package/gs/testing/testing.ts +27 -10
  370. package/gs/time/meta.json +2 -2
  371. package/gs/time/time.test.ts +4 -0
  372. package/gs/time/time.ts +33 -2
  373. package/gs/unicode/unicode.test.ts +14 -3
  374. package/gs/unicode/unicode.ts +1 -5
  375. package/gs/unique/index.ts +9 -2
  376. package/package.json +3 -3
@@ -0,0 +1,238 @@
1
+ import * as $ from '@goscript/builtin/index.js'
2
+ import * as io from '@goscript/io/index.js'
3
+
4
+ export type PublicKey = $.Bytes
5
+ export type PrivateKey = $.Bytes
6
+ type Hash = number
7
+ type PublicKeyInterface = any
8
+ type PrivateKeyInterface = any
9
+ type SignerOpts = { HashFunc(): Hash }
10
+
11
+ export const PublicKeySize = 32
12
+ export const PrivateKeySize = 64
13
+ export const SignatureSize = 64
14
+ export const SeedSize = 32
15
+
16
+ const pkcs8Prefix = new Uint8Array([
17
+ 0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70,
18
+ 0x04, 0x22, 0x04, 0x20,
19
+ ])
20
+
21
+ export class Options {
22
+ public Hash: Hash = 0
23
+ public Context = ''
24
+
25
+ constructor(init?: Partial<{ Hash: Hash; Context: string }>) {
26
+ this.Hash = init?.Hash ?? 0
27
+ this.Context = init?.Context ?? ''
28
+ }
29
+
30
+ public HashFunc(): Hash {
31
+ return this.Hash
32
+ }
33
+ }
34
+
35
+ export function PublicKey_Equal(pub: PublicKey, x: PublicKeyInterface | null): boolean {
36
+ const [xx, ok] = $.typeAssertTuple<PublicKey>(x, 'ed25519.PublicKey')
37
+ return ok && bytesEqual(pub, xx)
38
+ }
39
+
40
+ export function PrivateKey_Public(priv: PrivateKey): PublicKeyInterface | null {
41
+ const publicKey = new Uint8Array(PublicKeySize)
42
+ publicKey.set($.bytesToUint8Array(priv).subarray(SeedSize, PrivateKeySize))
43
+ return $.namedValueInterfaceValue<PublicKeyInterface | null>(
44
+ publicKey,
45
+ 'ed25519.PublicKey',
46
+ { Equal: PublicKey_Equal },
47
+ )
48
+ }
49
+
50
+ export function PrivateKey_Equal(priv: PrivateKey, x: PrivateKeyInterface | null): boolean {
51
+ const [xx, ok] = $.typeAssertTuple<PrivateKey>(x, 'ed25519.PrivateKey')
52
+ return ok && bytesEqual(priv, xx)
53
+ }
54
+
55
+ export function PrivateKey_Seed(priv: PrivateKey): $.Bytes {
56
+ return new Uint8Array($.bytesToUint8Array(priv).subarray(0, SeedSize))
57
+ }
58
+
59
+ export async function PrivateKey_Sign(
60
+ priv: PrivateKey,
61
+ _rand: io.Reader | null,
62
+ message: $.Bytes,
63
+ opts: SignerOpts | null,
64
+ ): Promise<[$.Bytes, $.GoError]> {
65
+ if (opts != null && opts.HashFunc() !== 0) {
66
+ return [null, new Ed25519Error('ed25519: expected opts.HashFunc() zero')]
67
+ }
68
+ return [await Sign(priv, message), null]
69
+ }
70
+
71
+ export async function GenerateKey(random: io.Reader | null): Promise<[PublicKey, PrivateKey, $.GoError]> {
72
+ const seed = new Uint8Array(SeedSize)
73
+ if (random == null) {
74
+ const subtle = subtleCrypto()
75
+ if (subtle == null) {
76
+ return [
77
+ null as PublicKey,
78
+ null as PrivateKey,
79
+ new Ed25519Error('crypto/ed25519: WebCrypto is unavailable'),
80
+ ]
81
+ }
82
+ globalThis.crypto.getRandomValues(seed)
83
+ } else {
84
+ const [, err] = await io.ReadFull(random, seed)
85
+ if (err != null) {
86
+ return [null as PublicKey, null as PrivateKey, err]
87
+ }
88
+ }
89
+
90
+ const privateKey = await NewKeyFromSeed(seed)
91
+ return [
92
+ $.mustTypeAssert<PublicKey>(
93
+ PrivateKey_Public(privateKey),
94
+ 'ed25519.PublicKey',
95
+ ),
96
+ privateKey,
97
+ null,
98
+ ]
99
+ }
100
+
101
+ export async function NewKeyFromSeed(seed: $.Bytes): Promise<PrivateKey> {
102
+ const seedBytes = $.bytesToUint8Array(seed)
103
+ if (seedBytes.length !== SeedSize) {
104
+ throw new Error(`ed25519: bad seed length: ${seedBytes.length}`)
105
+ }
106
+
107
+ const subtle = requireSubtle()
108
+ const key = await subtle.importKey(
109
+ 'pkcs8',
110
+ pkcs8FromSeed(seedBytes) as unknown as BufferSource,
111
+ { name: 'Ed25519' },
112
+ true,
113
+ ['sign'],
114
+ )
115
+ const jwk = await subtle.exportKey('jwk', key)
116
+ if (typeof jwk.x !== 'string') {
117
+ throw new Error('crypto/ed25519: imported key did not expose public key')
118
+ }
119
+
120
+ const publicKey = base64URLDecode(jwk.x)
121
+ const privateKey = new Uint8Array(PrivateKeySize)
122
+ privateKey.set(seedBytes, 0)
123
+ privateKey.set(publicKey, SeedSize)
124
+ return privateKey
125
+ }
126
+
127
+ export async function Sign(privateKey: PrivateKey, message: $.Bytes): Promise<$.Bytes> {
128
+ const priv = $.bytesToUint8Array(privateKey)
129
+ if (priv.length !== PrivateKeySize) {
130
+ throw new Error(`ed25519: bad private key length: ${priv.length}`)
131
+ }
132
+
133
+ const key = await requireSubtle().importKey(
134
+ 'pkcs8',
135
+ pkcs8FromSeed(priv.subarray(0, SeedSize)) as unknown as BufferSource,
136
+ { name: 'Ed25519' },
137
+ false,
138
+ ['sign'],
139
+ )
140
+ const sig = await requireSubtle().sign(
141
+ 'Ed25519',
142
+ key,
143
+ $.bytesToUint8Array(message) as unknown as BufferSource,
144
+ )
145
+ return new Uint8Array(sig)
146
+ }
147
+
148
+ export async function Verify(
149
+ publicKey: PublicKey,
150
+ message: $.Bytes,
151
+ sig: $.Bytes,
152
+ ): Promise<boolean> {
153
+ return (await VerifyWithOptions(publicKey, message, sig, new Options())) == null
154
+ }
155
+
156
+ export async function VerifyWithOptions(
157
+ publicKey: PublicKey,
158
+ message: $.Bytes,
159
+ sig: $.Bytes,
160
+ opts: Options | $.VarRef<Options> | null,
161
+ ): Promise<$.GoError> {
162
+ if ($.len(publicKey) !== PublicKeySize) {
163
+ throw new Error(`ed25519: bad public key length: ${$.len(publicKey)}`)
164
+ }
165
+ if ($.len(sig) !== SignatureSize) {
166
+ return new Ed25519Error('ed25519: bad signature length')
167
+ }
168
+
169
+ const options = $.pointerValueOrNil(opts)
170
+ if (options != null && (options.Hash !== 0 || options.Context !== '')) {
171
+ return new Ed25519Error('ed25519: only pure Ed25519 is supported')
172
+ }
173
+
174
+ const key = await requireSubtle().importKey(
175
+ 'raw',
176
+ $.bytesToUint8Array(publicKey) as unknown as BufferSource,
177
+ { name: 'Ed25519' },
178
+ false,
179
+ ['verify'],
180
+ )
181
+ const ok = await requireSubtle().verify(
182
+ 'Ed25519',
183
+ key,
184
+ $.bytesToUint8Array(sig) as unknown as BufferSource,
185
+ $.bytesToUint8Array(message) as unknown as BufferSource,
186
+ )
187
+ return ok ? null : new Ed25519Error('ed25519: invalid signature')
188
+ }
189
+
190
+ class Ed25519Error {
191
+ constructor(private readonly message: string) {}
192
+
193
+ Error(): string {
194
+ return this.message
195
+ }
196
+ }
197
+
198
+ function requireSubtle(): SubtleCrypto {
199
+ const subtle = subtleCrypto()
200
+ if (subtle == null) {
201
+ throw new Error('crypto/ed25519: WebCrypto Ed25519 is unavailable')
202
+ }
203
+ return subtle
204
+ }
205
+
206
+ function subtleCrypto(): SubtleCrypto | null {
207
+ const crypto = globalThis.crypto
208
+ if (crypto?.subtle && typeof crypto.subtle.importKey === 'function') {
209
+ return crypto.subtle
210
+ }
211
+ return null
212
+ }
213
+
214
+ function pkcs8FromSeed(seed: Uint8Array): Uint8Array {
215
+ const out = new Uint8Array(pkcs8Prefix.length + SeedSize)
216
+ out.set(pkcs8Prefix)
217
+ out.set(seed, pkcs8Prefix.length)
218
+ return out
219
+ }
220
+
221
+ function bytesEqual(a: $.Bytes, b: $.Bytes): boolean {
222
+ const aa = $.bytesToUint8Array(a)
223
+ const bb = $.bytesToUint8Array(b)
224
+ if (aa.length !== bb.length) {
225
+ return false
226
+ }
227
+ let diff = 0
228
+ for (let i = 0; i < aa.length; i++) {
229
+ diff |= aa[i] ^ bb[i]
230
+ }
231
+ return diff === 0
232
+ }
233
+
234
+ function base64URLDecode(value: string): Uint8Array {
235
+ const normalized = value.replace(/-/g, '+').replace(/_/g, '/')
236
+ const padded = normalized.padEnd(Math.ceil(normalized.length / 4) * 4, '=')
237
+ return Uint8Array.from(atob(padded), (c) => c.charCodeAt(0))
238
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "dependencies": [
3
+ "io"
4
+ ],
5
+ "asyncFunctions": {
6
+ "GenerateKey": true,
7
+ "NewKeyFromSeed": true,
8
+ "Sign": true,
9
+ "Verify": true,
10
+ "VerifyWithOptions": true,
11
+ "PrivateKey_Sign": true
12
+ }
13
+ }
@@ -0,0 +1,25 @@
1
+ import { describe, expect, test } from 'vitest'
2
+
3
+ import { ByteEq, Eq, LessOrEq, Select } from './index.js'
4
+
5
+ describe('crypto/internal/constanttime override', () => {
6
+ test('selects on any non-zero selector', () => {
7
+ expect(Select(0, 11, 22)).toBe(22)
8
+ expect(Select(1, 11, 22)).toBe(11)
9
+ expect(Select(7, 11, 22)).toBe(11)
10
+ })
11
+
12
+ test('compares bytes and int32 values', () => {
13
+ expect(ByteEq(0xff, 0xff)).toBe(1)
14
+ expect(ByteEq(0x1ff, 0xff)).toBe(1)
15
+ expect(ByteEq(0x01, 0x02)).toBe(0)
16
+ expect(Eq(12, 12)).toBe(1)
17
+ expect(Eq(12, 13)).toBe(0)
18
+ })
19
+
20
+ test('compares integer ordering', () => {
21
+ expect(LessOrEq(1, 1)).toBe(1)
22
+ expect(LessOrEq(1, 2)).toBe(1)
23
+ expect(LessOrEq(2, 1)).toBe(0)
24
+ })
25
+ })
@@ -0,0 +1,22 @@
1
+ import * as $ from '@goscript/builtin/index.js'
2
+
3
+ export function Select(v: number, x: number, y: number): number {
4
+ v = boolToUint8(v !== 0)
5
+ return (~(v - 1) & x) | ((v - 1) & y)
6
+ }
7
+
8
+ export function ByteEq(x: number, y: number): number {
9
+ return $.int(boolToUint8($.uint(x, 8) === $.uint(y, 8)))
10
+ }
11
+
12
+ export function Eq(x: number, y: number): number {
13
+ return $.int(boolToUint8($.int(x, 32) === $.int(y, 32)))
14
+ }
15
+
16
+ export function LessOrEq(x: number, y: number): number {
17
+ return $.int(boolToUint8(x <= y))
18
+ }
19
+
20
+ function boolToUint8(b: boolean): number {
21
+ return b ? 1 : 0
22
+ }
@@ -2,7 +2,58 @@ import { describe, expect, it } from 'vitest'
2
2
 
3
3
  import * as $ from '@goscript/builtin/index.js'
4
4
 
5
- import { Read, Reader, Text } from './index.js'
5
+ import { Int, Prime, Read, Reader, Text } from './index.js'
6
+
7
+ class TestInt {
8
+ private value = 0
9
+
10
+ constructor(value = 0) {
11
+ this.value = value
12
+ }
13
+
14
+ Sign(): number {
15
+ return Math.sign(this.value)
16
+ }
17
+
18
+ BitLen(): number {
19
+ return this.value.toString(2).length
20
+ }
21
+
22
+ SetBytes(bytes: Uint8Array): TestInt {
23
+ this.value = 0
24
+ for (const b of bytes) {
25
+ this.value = this.value * 256 + b
26
+ }
27
+ return this
28
+ }
29
+
30
+ Cmp(other: TestInt): number {
31
+ return Math.sign(this.value - other.value)
32
+ }
33
+
34
+ Value(): number {
35
+ return this.value
36
+ }
37
+
38
+ ProbablyPrime(): boolean {
39
+ if (this.value < 2) {
40
+ return false
41
+ }
42
+ for (let i = 2; i * i <= this.value; i++) {
43
+ if (this.value % i === 0) {
44
+ return false
45
+ }
46
+ }
47
+ return true
48
+ }
49
+ }
50
+
51
+ TestInt.__typeInfo = $.registerStructType(
52
+ 'big.Int',
53
+ () => new TestInt(),
54
+ [],
55
+ TestInt,
56
+ )
6
57
 
7
58
  describe('crypto/rand override', () => {
8
59
  it('fills byte slices from Web Crypto', () => {
@@ -29,4 +80,41 @@ describe('crypto/rand override', () => {
29
80
  expect(token).toHaveLength(26)
30
81
  expect(token).toMatch(/^[A-Z2-7]+$/)
31
82
  })
83
+
84
+ it('generates integers below max from an io.Reader', () => {
85
+ const reader = {
86
+ Read(dst: Uint8Array): [number, $.GoError] {
87
+ dst[0] = 42
88
+ return [dst.length, null]
89
+ },
90
+ }
91
+
92
+ const [n, err] = Int(reader, new TestInt(100))
93
+
94
+ expect(err).toBeNull()
95
+ expect(n.Value()).toBe(42)
96
+ })
97
+
98
+ it('generates probable primes with the requested bit length', async () => {
99
+ const reader = {
100
+ Read(dst: Uint8Array): [number, $.GoError] {
101
+ dst.fill(0)
102
+ return [dst.length, null]
103
+ },
104
+ }
105
+
106
+ const [prime, err] = await Prime(reader, 8)
107
+
108
+ expect(err).toBeNull()
109
+ expect(prime.Value()).toBe(193)
110
+ expect(prime.BitLen()).toBe(8)
111
+ expect(prime.ProbablyPrime()).toBe(true)
112
+ })
113
+
114
+ it('rejects prime sizes below two bits', async () => {
115
+ const [prime, err] = await Prime(Reader, 1)
116
+
117
+ expect(prime).toBeNull()
118
+ expect(err?.Error()).toBe('crypto/rand: prime size must be at least 2-bit')
119
+ })
32
120
  })
@@ -35,6 +35,75 @@ export function Read(b: $.Bytes): [number, $.GoError] {
35
35
  return [n, null]
36
36
  }
37
37
 
38
+ export function Int(rand: io.Reader | null, max: any): [any, $.GoError] {
39
+ if (max == null || typeof max.Sign !== 'function' || max.Sign() <= 0) {
40
+ return [null, new RandError('crypto/rand: argument to Int is <= 0')]
41
+ }
42
+
43
+ const bitLen = max.BitLen()
44
+ const byteLen = Math.ceil(bitLen / 8)
45
+ const excessBits = byteLen * 8 - bitLen
46
+ const reader = rand ?? Reader
47
+
48
+ while (true) {
49
+ const bytes = new Uint8Array(byteLen)
50
+ const [n, err] = reader.Read(bytes)
51
+ if (err != null) {
52
+ return [null, err]
53
+ }
54
+ if (n !== byteLen) {
55
+ return [null, io.ErrUnexpectedEOF]
56
+ }
57
+ if (excessBits > 0) {
58
+ bytes[0] &= 0xff >>> excessBits
59
+ }
60
+
61
+ const candidate = new max.constructor()
62
+ candidate.SetBytes(bytes)
63
+ if (candidate.Cmp(max) < 0) {
64
+ return [candidate, null]
65
+ }
66
+ }
67
+ }
68
+
69
+ export async function Prime(
70
+ rand: io.Reader | null,
71
+ bits: number,
72
+ ): Promise<[any, $.GoError]> {
73
+ if (bits < 2) {
74
+ return [null, new RandError('crypto/rand: prime size must be at least 2-bit')]
75
+ }
76
+
77
+ const bitOffset = bits % 8
78
+ const topBits = bitOffset === 0 ? 8 : bitOffset
79
+ const bytes = new Uint8Array(Math.ceil(bits / 8))
80
+ const reader = rand ?? Reader
81
+
82
+ while (true) {
83
+ const err = readFull(reader, bytes)
84
+ if (err != null) {
85
+ return [null, err]
86
+ }
87
+
88
+ bytes[0] &= (1 << topBits) - 1
89
+ if (topBits >= 2) {
90
+ bytes[0] |= 3 << (topBits - 2)
91
+ } else {
92
+ bytes[0] |= 1
93
+ if (bytes.length > 1) {
94
+ bytes[1] |= 0x80
95
+ }
96
+ }
97
+ bytes[bytes.length - 1] |= 1
98
+
99
+ const candidate = newBigInt()
100
+ candidate.SetBytes(bytes)
101
+ if (await candidate.ProbablyPrime(20)) {
102
+ return [candidate, null]
103
+ }
104
+ }
105
+ }
106
+
38
107
  export function Text(): string {
39
108
  const src = new Uint8Array(26)
40
109
  const [, err] = Read(src)
@@ -49,6 +118,37 @@ export function Text(): string {
49
118
  return out
50
119
  }
51
120
 
121
+ function newBigInt(): any {
122
+ const info = $.getTypeByName('big.Int') as
123
+ | { zeroValue?: unknown; ctor?: new () => unknown }
124
+ | undefined
125
+ if (info?.zeroValue !== undefined) {
126
+ return typeof info.zeroValue === 'function'
127
+ ? (info.zeroValue as () => unknown)()
128
+ : info.zeroValue
129
+ }
130
+ if (info?.ctor != null) {
131
+ return new info.ctor()
132
+ }
133
+ throw new Error('crypto/rand: math/big.Int type is not registered')
134
+ }
135
+
136
+ function readFull(reader: io.Reader, dst: Uint8Array): $.GoError {
137
+ let offset = 0
138
+ while (offset < dst.length) {
139
+ const chunk = dst.subarray(offset)
140
+ const [n, err] = reader.Read(chunk)
141
+ if (err != null) {
142
+ return err
143
+ }
144
+ if (n <= 0) {
145
+ return io.ErrUnexpectedEOF
146
+ }
147
+ offset += n
148
+ }
149
+ return null
150
+ }
151
+
52
152
  function fillSecureBytes(dst: $.Bytes): $.GoError {
53
153
  const length = $.len(dst)
54
154
  if (length === 0) {
@@ -57,7 +157,9 @@ function fillSecureBytes(dst: $.Bytes): $.GoError {
57
157
 
58
158
  const crypto = secureCrypto()
59
159
  if (crypto == null) {
60
- return new RandError('crypto/rand: Web Crypto getRandomValues is unavailable')
160
+ return new RandError(
161
+ 'crypto/rand: Web Crypto getRandomValues is unavailable',
162
+ )
61
163
  }
62
164
 
63
165
  if (dst instanceof Uint8Array) {
@@ -1,5 +1,8 @@
1
1
  {
2
2
  "dependencies": [
3
3
  "io"
4
- ]
4
+ ],
5
+ "asyncFunctions": {
6
+ "Prime": true
7
+ }
5
8
  }
@@ -0,0 +1,28 @@
1
+ import { createHash } from 'node:crypto'
2
+ import { describe, expect, it } from 'vitest'
3
+
4
+ import { New, Sum } from './index.js'
5
+
6
+ describe('crypto/sha1 override', () => {
7
+ it('matches Node digest', async () => {
8
+ const data = new TextEncoder().encode('goscript sha1')
9
+
10
+ expect(toHex(await Sum(data))).toBe(nodeHash(data))
11
+ })
12
+
13
+ it('supports incremental hash.Hash use', async () => {
14
+ const h = New()
15
+ h.Write(new TextEncoder().encode('go'))
16
+ h.Write(new TextEncoder().encode('script'))
17
+
18
+ expect(toHex(await h.Sum(null))).toBe(nodeHash(new TextEncoder().encode('goscript')))
19
+ })
20
+ })
21
+
22
+ function nodeHash(data: Uint8Array): string {
23
+ return createHash('sha1').update(data).digest('hex')
24
+ }
25
+
26
+ function toHex(value: Uint8Array): string {
27
+ return Buffer.from(value).toString('hex')
28
+ }
@@ -0,0 +1,130 @@
1
+ import * as $ from '@goscript/builtin/index.js'
2
+ import {
3
+ getHostRuntime,
4
+ type NodeCryptoHash,
5
+ } from '@goscript/builtin/hostio.js'
6
+
7
+ export const Size = 20
8
+ export const BlockSize = 64
9
+
10
+ class Sha1Error {
11
+ constructor(private readonly message: string) {}
12
+
13
+ Error(): string {
14
+ return this.message
15
+ }
16
+ }
17
+
18
+ class Digest {
19
+ private chunks: Uint8Array[] = []
20
+ private dataLength = 0
21
+ private hash: NodeCryptoHash | null
22
+ private canCopyHash: boolean
23
+
24
+ constructor() {
25
+ this.hash = createNodeHash()
26
+ this.canCopyHash = typeof this.hash?.copy === 'function'
27
+ }
28
+
29
+ Write(p: $.Bytes): [number, $.GoError] {
30
+ const bytes = $.bytesToUint8Array(p)
31
+ this.hash?.update(bytes)
32
+ if (!this.canCopyHash) {
33
+ this.chunks.push(bytes.slice())
34
+ this.dataLength += bytes.length
35
+ }
36
+ return [bytes.length, null]
37
+ }
38
+
39
+ async Sum(b: $.Bytes): Promise<$.Bytes> {
40
+ const digest =
41
+ this.canCopyHash ?
42
+ new Uint8Array(this.hash!.copy!().digest())
43
+ : await sum(this.snapshotBytes())
44
+ return appendDigest($.bytesToUint8Array(b), digest)
45
+ }
46
+
47
+ Reset(): void {
48
+ this.chunks = []
49
+ this.dataLength = 0
50
+ this.hash = createNodeHash()
51
+ this.canCopyHash = typeof this.hash?.copy === 'function'
52
+ }
53
+
54
+ Size(): number {
55
+ return Size
56
+ }
57
+
58
+ BlockSize(): number {
59
+ return BlockSize
60
+ }
61
+
62
+ private snapshotBytes(): Uint8Array {
63
+ return concatChunks(this.chunks, this.dataLength)
64
+ }
65
+ }
66
+
67
+ export function New(): any {
68
+ return new Digest()
69
+ }
70
+
71
+ export async function Sum(data: $.Bytes): Promise<Uint8Array> {
72
+ return sum(data)
73
+ }
74
+
75
+ async function sum(data: $.Bytes): Promise<Uint8Array> {
76
+ const hash = createNodeHash()
77
+ if (hash != null) {
78
+ return new Uint8Array(hash.update($.bytesToUint8Array(data)).digest())
79
+ }
80
+
81
+ const subtle = subtleCrypto()
82
+ if (subtle == null) {
83
+ throw new Error(
84
+ new Sha1Error('crypto/sha1: WebCrypto digest is unavailable').Error(),
85
+ )
86
+ }
87
+
88
+ const digest = await subtle.digest(
89
+ 'SHA-1',
90
+ $.bytesToUint8Array(data) as unknown as BufferSource,
91
+ )
92
+ return new Uint8Array(digest)
93
+ }
94
+
95
+ function appendDigest(prefix: Uint8Array, digest: Uint8Array): Uint8Array {
96
+ const out = new Uint8Array(prefix.length + digest.length)
97
+ out.set(prefix)
98
+ out.set(digest, prefix.length)
99
+ return out
100
+ }
101
+
102
+ function createNodeHash(): NodeCryptoHash | null {
103
+ const nodeCrypto = getHostRuntime().nodeCrypto
104
+ if (!nodeCrypto?.createHash) {
105
+ return null
106
+ }
107
+ try {
108
+ return nodeCrypto.createHash('sha1')
109
+ } catch {
110
+ return null
111
+ }
112
+ }
113
+
114
+ function concatChunks(chunks: Uint8Array[], length: number): Uint8Array {
115
+ const out = new Uint8Array(length)
116
+ let offset = 0
117
+ for (const chunk of chunks) {
118
+ out.set(chunk, offset)
119
+ offset += chunk.length
120
+ }
121
+ return out
122
+ }
123
+
124
+ function subtleCrypto(): SubtleCrypto | null {
125
+ const crypto = globalThis.crypto
126
+ if (crypto?.subtle && typeof crypto.subtle.digest === 'function') {
127
+ return crypto.subtle
128
+ }
129
+ return null
130
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "asyncFunctions": {
3
+ "Sum": true
4
+ },
5
+ "asyncMethods": {
6
+ "Digest.Sum": true
7
+ }
8
+ }