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.
- package/README.md +267 -255
- package/cmd/goscript/cmd-test.go +286 -0
- package/cmd/goscript/cmd-test_test.go +76 -0
- package/cmd/goscript/cmd_compile.go +9 -0
- package/cmd/goscript/main.go +1 -0
- package/compiler/build-flags.go +38 -0
- package/compiler/compile-request.go +33 -0
- package/compiler/compiler.go +1 -1
- package/compiler/compliance_test.go +0 -10
- package/compiler/config.go +2 -0
- package/compiler/gotest/owner.go +24 -0
- package/compiler/gotest/package-result.go +69 -0
- package/compiler/gotest/request.go +210 -0
- package/compiler/gotest/result.go +28 -0
- package/compiler/gotest/runner.go +1225 -0
- package/compiler/gotest/runner_test.go +1271 -0
- package/compiler/gotest/test.go +9 -0
- package/compiler/index.test.ts +1 -1
- package/compiler/lowered-program.go +80 -21
- package/compiler/lowering.go +6754 -602
- package/compiler/override-facts.go +357 -0
- package/compiler/override-registry.go +52 -190
- package/compiler/override-registry_test.go +182 -0
- package/compiler/package-graph.go +50 -27
- package/compiler/package-graph_test.go +99 -9
- package/compiler/package-test-function.go +9 -0
- package/compiler/package-test-graph-package.go +40 -0
- package/compiler/package-test-graph-variant.go +129 -0
- package/compiler/package-test-graph.go +112 -0
- package/compiler/package-test-graph_test.go +202 -0
- package/compiler/runtime-contract.go +229 -29
- package/compiler/runtime-contract_test.go +44 -30
- package/compiler/semantic-model-types.go +25 -6
- package/compiler/semantic-model.go +819 -74
- package/compiler/semantic-model_test.go +104 -0
- package/compiler/service.go +10 -4
- package/compiler/skeleton_test.go +2777 -524
- package/compiler/tsworkspace/owner-process-unix_test.go +72 -0
- package/compiler/tsworkspace/owner.go +342 -0
- package/compiler/tsworkspace/owner_test.go +93 -0
- package/compiler/tsworkspace/result.go +17 -0
- package/compiler/tsworkspace/tool-process-other.go +14 -0
- package/compiler/tsworkspace/tool-process-unix.go +19 -0
- package/compiler/typescript-emitter.go +576 -86
- package/compiler/wasm/compile.go +1 -1
- package/compiler/wasm/compile_test.go +61 -11
- package/compiler/wasm_api.go +172 -7
- package/dist/gs/builtin/builtin.d.ts +40 -3
- package/dist/gs/builtin/builtin.js +430 -22
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/channel.d.ts +32 -10
- package/dist/gs/builtin/channel.js +119 -25
- package/dist/gs/builtin/channel.js.map +1 -1
- package/dist/gs/builtin/defer.d.ts +1 -0
- package/dist/gs/builtin/defer.js +12 -2
- package/dist/gs/builtin/defer.js.map +1 -1
- package/dist/gs/builtin/hostio.d.ts +9 -0
- package/dist/gs/builtin/hostio.js +25 -0
- package/dist/gs/builtin/hostio.js.map +1 -1
- package/dist/gs/builtin/map.js +40 -6
- package/dist/gs/builtin/map.js.map +1 -1
- package/dist/gs/builtin/print.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +64 -10
- package/dist/gs/builtin/slice.js +619 -244
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +7 -2
- package/dist/gs/builtin/type.js +128 -29
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +7 -0
- package/dist/gs/builtin/varRef.js +23 -0
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +74 -70
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/iter.gs.js +13 -13
- package/dist/gs/bytes/iter.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.js +20 -18
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +26 -0
- package/dist/gs/compress/zlib/index.js +168 -0
- package/dist/gs/compress/zlib/index.js.map +1 -0
- package/dist/gs/context/context.d.ts +6 -5
- package/dist/gs/context/context.js +17 -12
- package/dist/gs/context/context.js.map +1 -1
- package/dist/gs/crypto/ecdh/index.d.ts +52 -0
- package/dist/gs/crypto/ecdh/index.js +226 -0
- package/dist/gs/crypto/ecdh/index.js.map +1 -0
- package/dist/gs/crypto/ed25519/index.d.ts +34 -0
- package/dist/gs/crypto/ed25519/index.js +160 -0
- package/dist/gs/crypto/ed25519/index.js.map +1 -0
- package/dist/gs/crypto/internal/constanttime/index.d.ts +4 -0
- package/dist/gs/crypto/internal/constanttime/index.js +18 -0
- package/dist/gs/crypto/internal/constanttime/index.js.map +1 -0
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.d.ts +1 -0
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.js +2 -0
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.js.map +1 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.d.ts +1 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.js +2 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.js.map +1 -0
- package/dist/gs/crypto/rand/index.d.ts +2 -0
- package/dist/gs/crypto/rand/index.js +85 -0
- package/dist/gs/crypto/rand/index.js.map +1 -1
- package/dist/gs/crypto/sha256/index.d.ts +8 -0
- package/dist/gs/crypto/sha256/index.js +118 -0
- package/dist/gs/crypto/sha256/index.js.map +1 -0
- package/dist/gs/crypto/sha512/index.d.ts +14 -0
- package/dist/gs/crypto/sha512/index.js +129 -0
- package/dist/gs/crypto/sha512/index.js.map +1 -0
- package/dist/gs/embed/index.d.ts +7 -0
- package/dist/gs/embed/index.js +16 -0
- package/dist/gs/embed/index.js.map +1 -0
- package/dist/gs/encoding/json/index.d.ts +4 -0
- package/dist/gs/encoding/json/index.js +33 -0
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/errors/errors.d.ts +4 -0
- package/dist/gs/errors/errors.js +108 -4
- package/dist/gs/errors/errors.js.map +1 -1
- package/dist/gs/fmt/fmt.d.ts +4 -4
- package/dist/gs/fmt/fmt.js +42 -11
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +37 -2
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +245 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +189 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +861 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +217 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +814 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -0
- package/dist/gs/github.com/aperturerobotics/util/conc/index.d.ts +20 -0
- package/dist/gs/github.com/aperturerobotics/util/conc/index.js +134 -0
- package/dist/gs/github.com/aperturerobotics/util/conc/index.js.map +1 -0
- package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
- package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.d.ts +3 -0
- package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js +50 -0
- package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js.map +1 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.d.ts +9 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js +72 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -0
- package/dist/gs/github.com/mr-tron/base58/base58/index.d.ts +27 -0
- package/dist/gs/github.com/mr-tron/base58/base58/index.js +172 -0
- package/dist/gs/github.com/mr-tron/base58/base58/index.js.map +1 -0
- package/dist/gs/github.com/zeebo/blake3/internal/consts/index.d.ts +21 -0
- package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js +22 -0
- package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js.map +1 -0
- package/dist/gs/go/internal/scannerhooks/index.d.ts +3 -0
- package/dist/gs/go/internal/scannerhooks/index.js +5 -0
- package/dist/gs/go/internal/scannerhooks/index.js.map +1 -0
- package/dist/gs/go/scanner/index.d.ts +13 -0
- package/dist/gs/go/scanner/index.js +35 -0
- package/dist/gs/go/scanner/index.js.map +1 -1
- package/dist/gs/go/token/index.d.ts +156 -0
- package/dist/gs/go/token/index.js +507 -4
- package/dist/gs/go/token/index.js.map +1 -1
- package/dist/gs/hash/fnv/index.d.ts +57 -0
- package/dist/gs/hash/fnv/index.js +299 -0
- package/dist/gs/hash/fnv/index.js.map +1 -0
- package/dist/gs/hash/index.d.ts +17 -0
- package/dist/gs/hash/index.js +94 -0
- package/dist/gs/hash/index.js.map +1 -0
- package/dist/gs/internal/abi/index.d.ts +4 -0
- package/dist/gs/internal/abi/index.js +10 -0
- package/dist/gs/internal/abi/index.js.map +1 -1
- package/dist/gs/internal/bytealg/index.d.ts +2 -0
- package/dist/gs/internal/bytealg/index.js +14 -0
- package/dist/gs/internal/bytealg/index.js.map +1 -1
- package/dist/gs/internal/byteorder/index.d.ts +8 -2
- package/dist/gs/internal/byteorder/index.js +56 -25
- package/dist/gs/internal/byteorder/index.js.map +1 -1
- package/dist/gs/internal/godebug/index.d.ts +12 -0
- package/dist/gs/internal/godebug/index.js +30 -0
- package/dist/gs/internal/godebug/index.js.map +1 -0
- package/dist/gs/io/fs/index.d.ts +1 -0
- package/dist/gs/io/fs/index.js +1 -0
- package/dist/gs/io/fs/index.js.map +1 -1
- package/dist/gs/io/fs/readlink.d.ts +8 -0
- package/dist/gs/io/fs/readlink.js +60 -0
- package/dist/gs/io/fs/readlink.js.map +1 -0
- package/dist/gs/io/fs/walk.d.ts +3 -3
- package/dist/gs/io/fs/walk.js +7 -7
- package/dist/gs/io/fs/walk.js.map +1 -1
- package/dist/gs/io/io.d.ts +40 -6
- package/dist/gs/io/io.js +151 -26
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/iter/iter.d.ts +3 -2
- package/dist/gs/iter/iter.js.map +1 -1
- package/dist/gs/maps/iter.d.ts +5 -5
- package/dist/gs/maps/iter.js +48 -21
- package/dist/gs/maps/iter.js.map +1 -1
- package/dist/gs/maps/maps.d.ts +6 -6
- package/dist/gs/maps/maps.js +1 -1
- package/dist/gs/maps/maps.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +13 -4
- package/dist/gs/math/bits/index.js +70 -48
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/math/const.gs.d.ts +5 -5
- package/dist/gs/math/const.gs.js +4 -4
- package/dist/gs/math/const.gs.js.map +1 -1
- package/dist/gs/mime/index.d.ts +1 -0
- package/dist/gs/mime/index.js +52 -0
- package/dist/gs/mime/index.js.map +1 -0
- package/dist/gs/net/http/httptest/index.d.ts +30 -0
- package/dist/gs/net/http/httptest/index.js +101 -0
- package/dist/gs/net/http/httptest/index.js.map +1 -0
- package/dist/gs/net/http/index.d.ts +131 -0
- package/dist/gs/net/http/index.js +307 -0
- package/dist/gs/net/http/index.js.map +1 -0
- package/dist/gs/net/http/pprof/index.d.ts +8 -0
- package/dist/gs/net/http/pprof/index.js +59 -0
- package/dist/gs/net/http/pprof/index.js.map +1 -0
- package/dist/gs/os/dir_unix.gs.js +2 -2
- package/dist/gs/os/dir_unix.gs.js.map +1 -1
- package/dist/gs/os/error.gs.js +9 -7
- package/dist/gs/os/error.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.js +95 -15
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/path/filepath/match.js +165 -3
- package/dist/gs/path/filepath/match.js.map +1 -1
- package/dist/gs/path/filepath/path.d.ts +8 -4
- package/dist/gs/path/filepath/path.js +192 -8
- package/dist/gs/path/filepath/path.js.map +1 -1
- package/dist/gs/path/path.d.ts +4 -1
- package/dist/gs/path/path.js +16 -4
- package/dist/gs/path/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +4 -3
- package/dist/gs/reflect/index.js +3 -2
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/iter.js +2 -2
- package/dist/gs/reflect/iter.js.map +1 -1
- package/dist/gs/reflect/map.js +29 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +31 -9
- package/dist/gs/reflect/type.js +536 -43
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.d.ts +1 -0
- package/dist/gs/reflect/types.js +3 -1
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/value.d.ts +4 -1
- package/dist/gs/reflect/value.js +39 -1
- package/dist/gs/reflect/value.js.map +1 -1
- package/dist/gs/reflect/visiblefields.js +1 -1
- package/dist/gs/reflect/visiblefields.js.map +1 -1
- package/dist/gs/runtime/debug/index.d.ts +41 -0
- package/dist/gs/runtime/debug/index.js +66 -0
- package/dist/gs/runtime/debug/index.js.map +1 -0
- package/dist/gs/runtime/pprof/index.d.ts +20 -0
- package/dist/gs/runtime/pprof/index.js +85 -0
- package/dist/gs/runtime/pprof/index.js.map +1 -0
- package/dist/gs/runtime/runtime.d.ts +35 -3
- package/dist/gs/runtime/runtime.js +72 -0
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/runtime/trace/index.d.ts +19 -0
- package/dist/gs/runtime/trace/index.js +64 -0
- package/dist/gs/runtime/trace/index.js.map +1 -0
- package/dist/gs/slices/slices.d.ts +42 -8
- package/dist/gs/slices/slices.js +425 -11
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/sort/slice.gs.d.ts +5 -3
- package/dist/gs/sort/slice.gs.js +60 -22
- package/dist/gs/sort/slice.gs.js.map +1 -1
- package/dist/gs/sort/sort.gs.d.ts +4 -4
- package/dist/gs/sort/sort.gs.js +11 -8
- package/dist/gs/sort/sort.gs.js.map +1 -1
- package/dist/gs/strings/builder.d.ts +1 -1
- package/dist/gs/strings/builder.js +29 -19
- package/dist/gs/strings/builder.js.map +1 -1
- package/dist/gs/strings/iter.js +140 -75
- package/dist/gs/strings/iter.js.map +1 -1
- package/dist/gs/strings/replace.js +2 -2
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/strings/strings.js +52 -6
- package/dist/gs/strings/strings.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.d.ts +9 -8
- package/dist/gs/sync/atomic/type.gs.js +0 -2
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +8 -3
- package/dist/gs/sync/sync.js +66 -11
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/constants.d.ts +36 -24
- package/dist/gs/syscall/constants.js +12 -0
- package/dist/gs/syscall/constants.js.map +1 -1
- package/dist/gs/syscall/errors.d.ts +117 -111
- package/dist/gs/syscall/errors.js +45 -0
- package/dist/gs/syscall/errors.js.map +1 -1
- package/dist/gs/syscall/fs.d.ts +37 -0
- package/dist/gs/syscall/fs.js +102 -0
- package/dist/gs/syscall/fs.js.map +1 -1
- package/dist/gs/syscall/js/index.d.ts +90 -0
- package/dist/gs/syscall/js/index.js +383 -0
- package/dist/gs/syscall/js/index.js.map +1 -0
- package/dist/gs/syscall/types.d.ts +26 -1
- package/dist/gs/syscall/types.js +45 -1
- package/dist/gs/syscall/types.js.map +1 -1
- package/dist/gs/testing/index.d.ts +1 -0
- package/dist/gs/testing/index.js +2 -0
- package/dist/gs/testing/index.js.map +1 -0
- package/dist/gs/testing/testing.d.ts +78 -0
- package/dist/gs/testing/testing.js +318 -0
- package/dist/gs/testing/testing.js.map +1 -0
- package/dist/gs/time/time.d.ts +41 -4
- package/dist/gs/time/time.js +227 -36
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unicode/unicode.d.ts +23 -1
- package/dist/gs/unicode/unicode.js +79 -10
- package/dist/gs/unicode/unicode.js.map +1 -1
- package/dist/gs/unicode/utf8/utf8.d.ts +4 -4
- package/dist/gs/unicode/utf8/utf8.js +24 -11
- package/dist/gs/unicode/utf8/utf8.js.map +1 -1
- package/dist/gs/unique/index.d.ts +11 -0
- package/dist/gs/unique/index.js +76 -0
- package/dist/gs/unique/index.js.map +1 -0
- package/go.mod +8 -8
- package/go.sum +14 -14
- package/gs/builtin/builtin.ts +585 -27
- package/gs/builtin/channel.ts +183 -29
- package/gs/builtin/defer.ts +13 -2
- package/gs/builtin/hostio.test.ts +1 -0
- package/gs/builtin/hostio.ts +38 -0
- package/gs/builtin/map.ts +46 -6
- package/gs/builtin/print.ts +12 -3
- package/gs/builtin/runtime-contract.test.ts +383 -10
- package/gs/builtin/slice.test.ts +70 -0
- package/gs/builtin/slice.ts +785 -265
- package/gs/builtin/type.ts +160 -41
- package/gs/builtin/varRef.ts +40 -1
- package/gs/bytes/buffer.gs.ts +74 -70
- package/gs/bytes/iter.gs.ts +13 -14
- package/gs/bytes/meta.json +8 -3
- package/gs/bytes/reader.gs.ts +20 -19
- package/gs/compress/zlib/index.test.ts +28 -0
- package/gs/compress/zlib/index.ts +200 -0
- package/gs/compress/zlib/meta.json +3 -0
- package/gs/context/context.test.ts +71 -0
- package/gs/context/context.ts +30 -29
- package/gs/crypto/ecdh/index.test.ts +43 -0
- package/gs/crypto/ecdh/index.ts +274 -0
- package/gs/crypto/ed25519/index.test.ts +41 -0
- package/gs/crypto/ed25519/index.ts +238 -0
- package/gs/crypto/ed25519/meta.json +13 -0
- package/gs/crypto/internal/constanttime/index.test.ts +25 -0
- package/gs/crypto/internal/constanttime/index.ts +22 -0
- package/gs/crypto/internal/fips140deps/byteorder/index.ts +1 -0
- package/gs/crypto/internal/fips140deps/godebug/index.ts +1 -0
- package/gs/crypto/rand/index.test.ts +89 -1
- package/gs/crypto/rand/index.ts +103 -1
- package/gs/crypto/rand/meta.json +4 -1
- package/gs/crypto/sha256/index.test.ts +78 -0
- package/gs/crypto/sha256/index.ts +150 -0
- package/gs/crypto/sha256/meta.json +9 -0
- package/gs/crypto/sha512/index.test.ts +31 -0
- package/gs/crypto/sha512/index.ts +161 -0
- package/gs/crypto/sha512/meta.json +11 -0
- package/gs/embed/index.ts +20 -0
- package/gs/embed/meta.json +5 -0
- package/gs/encoding/json/index.test.ts +39 -3
- package/gs/encoding/json/index.ts +45 -3
- package/gs/errors/errors.test.ts +85 -0
- package/gs/errors/errors.ts +132 -4
- package/gs/fmt/fmt.test.ts +3 -1
- package/gs/fmt/fmt.ts +55 -19
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +128 -1
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +342 -4
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +180 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +1084 -0
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +31 -0
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +1233 -0
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +46 -0
- package/gs/github.com/aperturerobotics/util/conc/index.test.ts +30 -0
- package/gs/github.com/aperturerobotics/util/conc/index.ts +172 -0
- package/gs/github.com/aperturerobotics/util/conc/meta.json +9 -0
- package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.ts +1 -4
- package/gs/github.com/hack-pad/safejs/internal/catch/index.test.ts +35 -0
- package/gs/github.com/hack-pad/safejs/internal/catch/index.ts +65 -0
- package/gs/github.com/hack-pad/safejs/internal/catch/meta.json +9 -0
- package/gs/github.com/klauspost/compress/internal/le/index.test.ts +37 -0
- package/gs/github.com/klauspost/compress/internal/le/index.ts +115 -0
- package/gs/github.com/mr-tron/base58/base58/index.test.ts +70 -0
- package/gs/github.com/mr-tron/base58/base58/index.ts +231 -0
- package/gs/github.com/mr-tron/base58/base58/meta.json +3 -0
- package/gs/github.com/zeebo/blake3/internal/consts/index.test.ts +46 -0
- package/gs/github.com/zeebo/blake3/internal/consts/index.ts +26 -0
- package/gs/go/internal/scannerhooks/index.test.ts +14 -0
- package/gs/go/internal/scannerhooks/index.ts +9 -0
- package/gs/go/scanner/index.test.ts +22 -0
- package/gs/go/scanner/index.ts +47 -0
- package/gs/go/token/index.test.ts +47 -1
- package/gs/go/token/index.ts +583 -4
- package/gs/hash/fnv/index.test.ts +67 -0
- package/gs/hash/fnv/index.ts +351 -0
- package/gs/hash/fnv/meta.json +3 -0
- package/gs/hash/index.test.ts +37 -0
- package/gs/hash/index.ts +118 -0
- package/gs/hash/meta.json +5 -0
- package/gs/internal/abi/index.test.ts +18 -0
- package/gs/internal/abi/index.ts +14 -0
- package/gs/internal/bytealg/index.test.ts +18 -0
- package/gs/internal/bytealg/index.ts +16 -0
- package/gs/internal/byteorder/index.test.ts +39 -0
- package/gs/internal/byteorder/index.ts +100 -27
- package/gs/internal/godebug/index.test.ts +16 -0
- package/gs/internal/godebug/index.ts +35 -0
- package/gs/io/fs/index.ts +1 -0
- package/gs/io/fs/meta.json +5 -0
- package/gs/io/fs/readlink.test.ts +43 -0
- package/gs/io/fs/readlink.ts +69 -0
- package/gs/io/fs/walk.test.ts +61 -0
- package/gs/io/fs/walk.ts +17 -9
- package/gs/io/io.ts +177 -31
- package/gs/io/meta.json +10 -2
- package/gs/iter/iter.ts +8 -2
- package/gs/maps/iter.ts +75 -26
- package/gs/maps/maps.test.ts +23 -0
- package/gs/maps/maps.ts +13 -11
- package/gs/math/bits/index.test.ts +20 -0
- package/gs/math/bits/index.ts +107 -64
- package/gs/math/const.gs.test.ts +11 -5
- package/gs/math/const.gs.ts +5 -6
- package/gs/mime/index.ts +60 -0
- package/gs/net/http/httptest/index.test.ts +53 -0
- package/gs/net/http/httptest/index.ts +120 -0
- package/gs/net/http/index.test.ts +148 -0
- package/gs/net/http/index.ts +432 -0
- package/gs/net/http/meta.json +6 -0
- package/gs/net/http/pprof/index.test.ts +47 -0
- package/gs/net/http/pprof/index.ts +65 -0
- package/gs/os/dir_unix.gs.ts +2 -3
- package/gs/os/error.gs.ts +9 -10
- package/gs/os/error.test.ts +41 -0
- package/gs/os/file_unix_js.test.ts +55 -0
- package/gs/os/tempfile.gs.test.ts +37 -10
- package/gs/os/types_js.gs.ts +96 -17
- package/gs/path/filepath/match.test.ts +31 -12
- package/gs/path/filepath/match.ts +181 -3
- package/gs/path/filepath/meta.json +6 -0
- package/gs/path/filepath/path.test.ts +80 -0
- package/gs/path/filepath/path.ts +244 -11
- package/gs/path/path.ts +20 -5
- package/gs/reflect/field.test.ts +63 -0
- package/gs/reflect/index.ts +5 -1
- package/gs/reflect/iter.ts +2 -2
- package/gs/reflect/map.test.ts +42 -1
- package/gs/reflect/map.ts +39 -0
- package/gs/reflect/type.ts +728 -65
- package/gs/reflect/typefor.test.ts +100 -0
- package/gs/reflect/types.ts +3 -1
- package/gs/reflect/value.ts +50 -1
- package/gs/reflect/visiblefields.ts +1 -1
- package/gs/runtime/debug/index.test.ts +45 -0
- package/gs/runtime/debug/index.ts +96 -0
- package/gs/runtime/pprof/index.test.ts +36 -0
- package/gs/runtime/pprof/index.ts +104 -0
- package/gs/runtime/pprof/meta.json +6 -0
- package/gs/runtime/runtime.test.ts +19 -0
- package/gs/runtime/runtime.ts +98 -3
- package/gs/runtime/trace/index.test.ts +45 -0
- package/gs/runtime/trace/index.ts +97 -0
- package/gs/runtime/trace/meta.json +7 -0
- package/gs/slices/meta.json +2 -1
- package/gs/slices/slices.test.ts +180 -0
- package/gs/slices/slices.ts +502 -15
- package/gs/sort/meta.json +7 -0
- package/gs/sort/slice.gs.ts +85 -26
- package/gs/sort/slice.test.ts +40 -0
- package/gs/sort/sort.gs.ts +16 -13
- package/gs/strings/builder.test.ts +8 -0
- package/gs/strings/builder.ts +33 -20
- package/gs/strings/iter.test.ts +5 -7
- package/gs/strings/iter.ts +146 -71
- package/gs/strings/replace.test.ts +1 -4
- package/gs/strings/replace.ts +6 -6
- package/gs/strings/strings.test.ts +4 -0
- package/gs/strings/strings.ts +54 -6
- package/gs/sync/atomic/type.gs.ts +13 -14
- package/gs/sync/meta.json +3 -1
- package/gs/sync/sync.test.ts +69 -1
- package/gs/sync/sync.ts +72 -13
- package/gs/syscall/constants.ts +39 -24
- package/gs/syscall/errors.ts +165 -112
- package/gs/syscall/fs.ts +195 -0
- package/gs/syscall/js/index.ts +485 -0
- package/gs/syscall/js/meta.json +4 -0
- package/gs/syscall/net.test.ts +111 -0
- package/gs/syscall/types.ts +63 -2
- package/gs/testing/index.ts +1 -0
- package/gs/testing/meta.json +5 -0
- package/gs/testing/testing.test.ts +146 -0
- package/gs/testing/testing.ts +399 -0
- package/gs/time/meta.json +2 -2
- package/gs/time/time.test.ts +110 -0
- package/gs/time/time.ts +309 -57
- package/gs/unicode/unicode.test.ts +36 -0
- package/gs/unicode/unicode.ts +115 -9
- package/gs/unicode/utf8/utf8.test.ts +13 -0
- package/gs/unicode/utf8/utf8.ts +28 -16
- package/gs/unique/index.ts +98 -0
- package/package.json +3 -2
|
@@ -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
|
})
|
package/gs/crypto/rand/index.ts
CHANGED
|
@@ -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(
|
|
160
|
+
return new RandError(
|
|
161
|
+
'crypto/rand: Web Crypto getRandomValues is unavailable',
|
|
162
|
+
)
|
|
61
163
|
}
|
|
62
164
|
|
|
63
165
|
if (dst instanceof Uint8Array) {
|
package/gs/crypto/rand/meta.json
CHANGED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest'
|
|
2
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
3
|
+
|
|
4
|
+
import { New, New224, Size, Size224, Sum224, Sum256 } from './index.js'
|
|
5
|
+
|
|
6
|
+
describe('crypto/sha256 override', () => {
|
|
7
|
+
test('sums with WebCrypto', async () => {
|
|
8
|
+
const sum = await Sum256($.stringToBytes('abc'))
|
|
9
|
+
expect(Array.from(sum)).toEqual([
|
|
10
|
+
186, 120, 22, 191, 143, 1, 207, 234, 65, 65, 64, 222, 93, 174, 34, 35,
|
|
11
|
+
176, 3, 97, 163, 150, 23, 122, 156, 180, 16, 255, 97, 242, 0, 21, 173,
|
|
12
|
+
])
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
test('streaming digest appends to prefix', async () => {
|
|
16
|
+
const digest = New()
|
|
17
|
+
expect(digest.Write($.stringToBytes('a'))).toEqual([1, null])
|
|
18
|
+
expect(digest.Write($.stringToBytes('bc'))).toEqual([2, null])
|
|
19
|
+
|
|
20
|
+
const out = await digest.Sum(new Uint8Array([1, 2]))
|
|
21
|
+
expect(Array.from(out).slice(0, 2)).toEqual([1, 2])
|
|
22
|
+
expect(out.length).toBe(Size + 2)
|
|
23
|
+
expect(Array.from(out).slice(2)).toEqual(
|
|
24
|
+
Array.from(await Sum256($.stringToBytes('abc'))),
|
|
25
|
+
)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('sums SHA-224 with host crypto', async () => {
|
|
29
|
+
const sum = await Sum224($.stringToBytes('abc'))
|
|
30
|
+
expect(Array.from(sum)).toEqual([
|
|
31
|
+
35, 9, 125, 34, 52, 5, 216, 34, 134, 66, 164, 119, 189, 162, 85, 179,
|
|
32
|
+
42, 173, 188, 228, 189, 160, 179, 247, 227, 108, 157, 167,
|
|
33
|
+
])
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
test('streaming SHA-224 digest appends to prefix', async () => {
|
|
37
|
+
const digest = New224()
|
|
38
|
+
expect(digest.Write($.stringToBytes('a'))).toEqual([1, null])
|
|
39
|
+
expect(digest.Write($.stringToBytes('bc'))).toEqual([2, null])
|
|
40
|
+
|
|
41
|
+
const out = await digest.Sum(new Uint8Array([1, 2]))
|
|
42
|
+
expect(Array.from(out).slice(0, 2)).toEqual([1, 2])
|
|
43
|
+
expect(out.length).toBe(Size224 + 2)
|
|
44
|
+
expect(Array.from(out).slice(2)).toEqual(
|
|
45
|
+
Array.from(await Sum224($.stringToBytes('abc'))),
|
|
46
|
+
)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('streaming Sum does not finalize the digest', async () => {
|
|
50
|
+
const digest = New()
|
|
51
|
+
expect(digest.Write($.stringToBytes('abc'))).toEqual([3, null])
|
|
52
|
+
|
|
53
|
+
const first = await digest.Sum(null)
|
|
54
|
+
expect(Array.from(first)).toEqual(
|
|
55
|
+
Array.from(await Sum256($.stringToBytes('abc'))),
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
expect(digest.Write($.stringToBytes('d'))).toEqual([1, null])
|
|
59
|
+
const second = await digest.Sum(null)
|
|
60
|
+
expect(Array.from(second)).toEqual(
|
|
61
|
+
Array.from(await Sum256($.stringToBytes('abcd'))),
|
|
62
|
+
)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
test('streaming digest handles many small writes', async () => {
|
|
66
|
+
const digest = New()
|
|
67
|
+
let data = ''
|
|
68
|
+
for (let i = 0; i < 4096; i++) {
|
|
69
|
+
const part = `key-${i};`
|
|
70
|
+
data += part
|
|
71
|
+
expect(digest.Write($.stringToBytes(part))).toEqual([part.length, null])
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
expect(Array.from(await digest.Sum(null))).toEqual(
|
|
75
|
+
Array.from(await Sum256($.stringToBytes(data))),
|
|
76
|
+
)
|
|
77
|
+
})
|
|
78
|
+
})
|
|
@@ -0,0 +1,150 @@
|
|
|
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 = 32
|
|
8
|
+
export const Size224 = 28
|
|
9
|
+
export const BlockSize = 64
|
|
10
|
+
|
|
11
|
+
type ShaAlgorithm = 'sha224' | 'sha256'
|
|
12
|
+
|
|
13
|
+
class Sha256Error {
|
|
14
|
+
constructor(private readonly message: string) {}
|
|
15
|
+
|
|
16
|
+
Error(): string {
|
|
17
|
+
return this.message
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
class Digest {
|
|
22
|
+
private chunks: Uint8Array[] = []
|
|
23
|
+
private dataLength = 0
|
|
24
|
+
private hash: NodeCryptoHash | null
|
|
25
|
+
private canCopyHash: boolean
|
|
26
|
+
|
|
27
|
+
constructor(private readonly algorithm: ShaAlgorithm) {
|
|
28
|
+
this.hash = createNodeHash(algorithm)
|
|
29
|
+
this.canCopyHash = typeof this.hash?.copy === 'function'
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
Write(p: $.Bytes): [number, $.GoError] {
|
|
33
|
+
const bytes = $.bytesToUint8Array(p)
|
|
34
|
+
this.hash?.update(bytes)
|
|
35
|
+
if (!this.canCopyHash) {
|
|
36
|
+
this.chunks.push(bytes.slice())
|
|
37
|
+
this.dataLength += bytes.length
|
|
38
|
+
}
|
|
39
|
+
return [bytes.length, null]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async Sum(b: $.Bytes): Promise<$.Bytes> {
|
|
43
|
+
const digest =
|
|
44
|
+
this.canCopyHash ?
|
|
45
|
+
new Uint8Array(this.hash!.copy!().digest())
|
|
46
|
+
: await sum(this.algorithm, this.snapshotBytes())
|
|
47
|
+
return appendDigest($.bytesToUint8Array(b), digest)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
Reset(): void {
|
|
51
|
+
this.chunks = []
|
|
52
|
+
this.dataLength = 0
|
|
53
|
+
this.hash = createNodeHash(this.algorithm)
|
|
54
|
+
this.canCopyHash = typeof this.hash?.copy === 'function'
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
Size(): number {
|
|
58
|
+
return this.algorithm === 'sha224' ? Size224 : Size
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
BlockSize(): number {
|
|
62
|
+
return BlockSize
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private snapshotBytes(): Uint8Array {
|
|
66
|
+
return concatChunks(this.chunks, this.dataLength)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function New(): any {
|
|
71
|
+
return new Digest('sha256')
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function New224(): any {
|
|
75
|
+
return new Digest('sha224')
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export async function Sum224(data: $.Bytes): Promise<Uint8Array> {
|
|
79
|
+
return sum('sha224', data)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export async function Sum256(data: $.Bytes): Promise<Uint8Array> {
|
|
83
|
+
return sum('sha256', data)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function sum(
|
|
87
|
+
algorithm: ShaAlgorithm,
|
|
88
|
+
data: $.Bytes,
|
|
89
|
+
): Promise<Uint8Array> {
|
|
90
|
+
const hash = createNodeHash(algorithm)
|
|
91
|
+
if (hash != null) {
|
|
92
|
+
return new Uint8Array(hash.update($.bytesToUint8Array(data)).digest())
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (algorithm === 'sha224') {
|
|
96
|
+
throw new Error(
|
|
97
|
+
new Sha256Error('crypto/sha256: SHA-224 digest is unavailable').Error(),
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const subtle = subtleCrypto()
|
|
102
|
+
if (subtle == null) {
|
|
103
|
+
throw new Error(
|
|
104
|
+
new Sha256Error('crypto/sha256: WebCrypto digest is unavailable').Error(),
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const digest = await subtle.digest(
|
|
109
|
+
'SHA-256',
|
|
110
|
+
$.bytesToUint8Array(data) as unknown as BufferSource,
|
|
111
|
+
)
|
|
112
|
+
return new Uint8Array(digest)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function appendDigest(prefix: Uint8Array, digest: Uint8Array): Uint8Array {
|
|
116
|
+
const out = new Uint8Array(prefix.length + digest.length)
|
|
117
|
+
out.set(prefix)
|
|
118
|
+
out.set(digest, prefix.length)
|
|
119
|
+
return out
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function createNodeHash(algorithm: ShaAlgorithm): NodeCryptoHash | null {
|
|
123
|
+
const nodeCrypto = getHostRuntime().nodeCrypto
|
|
124
|
+
if (!nodeCrypto?.createHash) {
|
|
125
|
+
return null
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
return nodeCrypto.createHash(algorithm)
|
|
129
|
+
} catch {
|
|
130
|
+
return null
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function concatChunks(chunks: Uint8Array[], length: number): Uint8Array {
|
|
135
|
+
const out = new Uint8Array(length)
|
|
136
|
+
let offset = 0
|
|
137
|
+
for (const chunk of chunks) {
|
|
138
|
+
out.set(chunk, offset)
|
|
139
|
+
offset += chunk.length
|
|
140
|
+
}
|
|
141
|
+
return out
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function subtleCrypto(): SubtleCrypto | null {
|
|
145
|
+
const crypto = globalThis.crypto
|
|
146
|
+
if (crypto?.subtle && typeof crypto.subtle.digest === 'function') {
|
|
147
|
+
return crypto.subtle
|
|
148
|
+
}
|
|
149
|
+
return null
|
|
150
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto'
|
|
2
|
+
import { describe, expect, it } from 'vitest'
|
|
3
|
+
|
|
4
|
+
import { New, Sum384, Sum512, Sum512_224, Sum512_256 } from './index.js'
|
|
5
|
+
|
|
6
|
+
describe('crypto/sha512 override', () => {
|
|
7
|
+
it('matches Node digests', async () => {
|
|
8
|
+
const data = new TextEncoder().encode('goscript sha512')
|
|
9
|
+
|
|
10
|
+
expect(toHex(await Sum512(data))).toBe(nodeHash('sha512', data))
|
|
11
|
+
expect(toHex(await Sum384(data))).toBe(nodeHash('sha384', data))
|
|
12
|
+
expect(toHex(await Sum512_224(data))).toBe(nodeHash('sha512-224', data))
|
|
13
|
+
expect(toHex(await Sum512_256(data))).toBe(nodeHash('sha512-256', data))
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('supports incremental hash.Hash use', async () => {
|
|
17
|
+
const h = New()
|
|
18
|
+
h.Write(new TextEncoder().encode('go'))
|
|
19
|
+
h.Write(new TextEncoder().encode('script'))
|
|
20
|
+
|
|
21
|
+
expect(toHex(await h.Sum(null))).toBe(nodeHash('sha512', new TextEncoder().encode('goscript')))
|
|
22
|
+
})
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
function nodeHash(algorithm: string, data: Uint8Array): string {
|
|
26
|
+
return createHash(algorithm).update(data).digest('hex')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function toHex(value: Uint8Array): string {
|
|
30
|
+
return Buffer.from(value).toString('hex')
|
|
31
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
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 = 64
|
|
8
|
+
export const Size224 = 28
|
|
9
|
+
export const Size256 = 32
|
|
10
|
+
export const Size384 = 48
|
|
11
|
+
export const BlockSize = 128
|
|
12
|
+
|
|
13
|
+
type ShaAlgorithm = 'sha384' | 'sha512' | 'sha512-224' | 'sha512-256'
|
|
14
|
+
|
|
15
|
+
class Digest {
|
|
16
|
+
private chunks: Uint8Array[] = []
|
|
17
|
+
private dataLength = 0
|
|
18
|
+
private hash: NodeCryptoHash | null
|
|
19
|
+
private canCopyHash: boolean
|
|
20
|
+
|
|
21
|
+
constructor(private readonly algorithm: ShaAlgorithm) {
|
|
22
|
+
this.hash = createNodeHash(algorithm)
|
|
23
|
+
this.canCopyHash = typeof this.hash?.copy === 'function'
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
Write(p: $.Bytes): [number, $.GoError] {
|
|
27
|
+
const bytes = $.bytesToUint8Array(p)
|
|
28
|
+
this.hash?.update(bytes)
|
|
29
|
+
if (!this.canCopyHash) {
|
|
30
|
+
this.chunks.push(bytes.slice())
|
|
31
|
+
this.dataLength += bytes.length
|
|
32
|
+
}
|
|
33
|
+
return [bytes.length, null]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async Sum(b: $.Bytes): Promise<$.Bytes> {
|
|
37
|
+
const digest =
|
|
38
|
+
this.canCopyHash ?
|
|
39
|
+
new Uint8Array(this.hash!.copy!().digest())
|
|
40
|
+
: await sum(this.algorithm, this.snapshotBytes())
|
|
41
|
+
return appendDigest($.bytesToUint8Array(b), digest)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
Reset(): void {
|
|
45
|
+
this.chunks = []
|
|
46
|
+
this.dataLength = 0
|
|
47
|
+
this.hash = createNodeHash(this.algorithm)
|
|
48
|
+
this.canCopyHash = typeof this.hash?.copy === 'function'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
Size(): number {
|
|
52
|
+
switch (this.algorithm) {
|
|
53
|
+
case 'sha384':
|
|
54
|
+
return Size384
|
|
55
|
+
case 'sha512-224':
|
|
56
|
+
return Size224
|
|
57
|
+
case 'sha512-256':
|
|
58
|
+
return Size256
|
|
59
|
+
default:
|
|
60
|
+
return Size
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
BlockSize(): number {
|
|
65
|
+
return BlockSize
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private snapshotBytes(): Uint8Array {
|
|
69
|
+
return concatChunks(this.chunks, this.dataLength)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function New(): any {
|
|
74
|
+
return new Digest('sha512')
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function New384(): any {
|
|
78
|
+
return new Digest('sha384')
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function New512_224(): any {
|
|
82
|
+
return new Digest('sha512-224')
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function New512_256(): any {
|
|
86
|
+
return new Digest('sha512-256')
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export async function Sum384(data: $.Bytes): Promise<Uint8Array> {
|
|
90
|
+
return sum('sha384', data)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export async function Sum512(data: $.Bytes): Promise<Uint8Array> {
|
|
94
|
+
return sum('sha512', data)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export async function Sum512_224(data: $.Bytes): Promise<Uint8Array> {
|
|
98
|
+
return sum('sha512-224', data)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export async function Sum512_256(data: $.Bytes): Promise<Uint8Array> {
|
|
102
|
+
return sum('sha512-256', data)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function sum(
|
|
106
|
+
algorithm: ShaAlgorithm,
|
|
107
|
+
data: $.Bytes,
|
|
108
|
+
): Promise<Uint8Array> {
|
|
109
|
+
const hash = createNodeHash(algorithm)
|
|
110
|
+
if (hash != null) {
|
|
111
|
+
return new Uint8Array(hash.update($.bytesToUint8Array(data)).digest())
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const subtle = subtleCrypto()
|
|
115
|
+
if (subtle == null || (algorithm !== 'sha384' && algorithm !== 'sha512')) {
|
|
116
|
+
throw new Error(`crypto/sha512: ${algorithm} digest is unavailable`)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const digest = await subtle.digest(
|
|
120
|
+
algorithm === 'sha384' ? 'SHA-384' : 'SHA-512',
|
|
121
|
+
$.bytesToUint8Array(data) as unknown as BufferSource,
|
|
122
|
+
)
|
|
123
|
+
return new Uint8Array(digest)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function appendDigest(prefix: Uint8Array, digest: Uint8Array): Uint8Array {
|
|
127
|
+
const out = new Uint8Array(prefix.length + digest.length)
|
|
128
|
+
out.set(prefix)
|
|
129
|
+
out.set(digest, prefix.length)
|
|
130
|
+
return out
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function createNodeHash(algorithm: ShaAlgorithm): NodeCryptoHash | null {
|
|
134
|
+
const nodeCrypto = getHostRuntime().nodeCrypto
|
|
135
|
+
if (!nodeCrypto?.createHash) {
|
|
136
|
+
return null
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
return nodeCrypto.createHash(algorithm)
|
|
140
|
+
} catch {
|
|
141
|
+
return null
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function concatChunks(chunks: Uint8Array[], length: number): Uint8Array {
|
|
146
|
+
const out = new Uint8Array(length)
|
|
147
|
+
let offset = 0
|
|
148
|
+
for (const chunk of chunks) {
|
|
149
|
+
out.set(chunk, offset)
|
|
150
|
+
offset += chunk.length
|
|
151
|
+
}
|
|
152
|
+
return out
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function subtleCrypto(): SubtleCrypto | null {
|
|
156
|
+
const crypto = globalThis.crypto
|
|
157
|
+
if (crypto?.subtle && typeof crypto.subtle.digest === 'function') {
|
|
158
|
+
return crypto.subtle
|
|
159
|
+
}
|
|
160
|
+
return null
|
|
161
|
+
}
|
|
@@ -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
|
+
}
|