goscript 0.1.3 → 0.2.0
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 +5 -2
- package/cmd/go_js_wasm_exec/main.go +201 -0
- package/cmd/go_js_wasm_exec/main_test.go +83 -0
- package/cmd/goscript/{cmd_compile.go → cmd-compile.go} +35 -8
- package/cmd/goscript/cmd-test.go +14 -0
- package/cmd/goscript/cmd-test_test.go +1 -1
- package/cmd/goscript/cmd_compile_test.go +105 -6
- package/compiler/build-flags.go +9 -10
- package/compiler/compile-request.go +12 -9
- package/compiler/compliance_test.go +0 -1
- package/compiler/config.go +2 -0
- package/compiler/gotest/request.go +28 -0
- package/compiler/gotest/runner.go +353 -27
- package/compiler/gotest/runner_test.go +400 -1
- package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
- package/compiler/gotest/testdata/browserapi/go.mod +3 -0
- package/compiler/lowered-program.go +24 -17
- package/compiler/lowering.go +988 -263
- package/compiler/lowering_bench_test.go +364 -0
- package/compiler/override-facts.go +15 -0
- package/compiler/override-parity-verifier.go +450 -0
- package/compiler/override-parity.go +122 -0
- package/compiler/override-registry_test.go +559 -0
- package/compiler/package-graph.go +61 -4
- package/compiler/package-graph_test.go +30 -0
- package/compiler/protobuf-ts-binding.go +514 -0
- package/compiler/protobuf-ts-binding_test.go +172 -0
- package/compiler/semantic-model-types.go +17 -4
- package/compiler/semantic-model.go +709 -72
- package/compiler/semantic-model_test.go +219 -0
- package/compiler/service.go +20 -1
- package/compiler/skeleton_test.go +1008 -20
- package/compiler/typescript-emitter.go +147 -15
- package/dist/gs/builtin/builtin.d.ts +2 -2
- package/dist/gs/builtin/builtin.js +20 -0
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +2 -1
- package/dist/gs/builtin/slice.js +34 -4
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +14 -6
- package/dist/gs/builtin/type.js +224 -64
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +11 -0
- package/dist/gs/builtin/varRef.js +57 -2
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +1 -1
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.js +1 -1
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +13 -6
- package/dist/gs/compress/zlib/index.js +131 -35
- package/dist/gs/compress/zlib/index.js.map +1 -1
- package/dist/gs/crypto/sha1/index.js +2 -5
- package/dist/gs/crypto/sha1/index.js.map +1 -1
- package/dist/gs/crypto/sha256/index.js +2 -5
- package/dist/gs/crypto/sha256/index.js.map +1 -1
- package/dist/gs/crypto/sha512/index.js +2 -5
- package/dist/gs/crypto/sha512/index.js.map +1 -1
- package/dist/gs/embed/index.d.ts +6 -0
- package/dist/gs/embed/index.js +210 -5
- package/dist/gs/embed/index.js.map +1 -1
- package/dist/gs/encoding/json/index.d.ts +114 -0
- package/dist/gs/encoding/json/index.js +544 -36
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/fmt/fmt.d.ts +3 -3
- package/dist/gs/fmt/fmt.js +29 -16
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +100 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +564 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.d.ts +45 -0
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js +229 -0
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js.map +1 -0
- package/dist/gs/github.com/pkg/errors/errors.js +54 -30
- package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
- package/dist/gs/go/scanner/index.d.ts +2 -0
- package/dist/gs/go/scanner/index.js +29 -5
- package/dist/gs/go/scanner/index.js.map +1 -1
- package/dist/gs/go/token/index.js +22 -6
- package/dist/gs/go/token/index.js.map +1 -1
- package/dist/gs/hash/index.d.ts +6 -0
- package/dist/gs/hash/index.js +20 -0
- package/dist/gs/hash/index.js.map +1 -1
- package/dist/gs/internal/goarch/index.d.ts +43 -3
- package/dist/gs/internal/goarch/index.js +42 -10
- package/dist/gs/internal/goarch/index.js.map +1 -1
- package/dist/gs/io/fs/fs.js +26 -14
- package/dist/gs/io/fs/fs.js.map +1 -1
- package/dist/gs/io/fs/readdir.js +8 -4
- package/dist/gs/io/fs/readdir.js.map +1 -1
- package/dist/gs/io/fs/sub.js +8 -1
- package/dist/gs/io/fs/sub.js.map +1 -1
- package/dist/gs/io/io.d.ts +12 -6
- package/dist/gs/io/io.js +87 -42
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +31 -5
- package/dist/gs/math/bits/index.js +29 -28
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/mime/index.d.ts +16 -0
- package/dist/gs/mime/index.js +315 -6
- package/dist/gs/mime/index.js.map +1 -1
- package/dist/gs/net/http/httptest/index.d.ts +12 -0
- package/dist/gs/net/http/httptest/index.js +85 -6
- package/dist/gs/net/http/httptest/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +303 -6
- package/dist/gs/net/http/index.js +1615 -58
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/os/dir_unix.gs.js +1 -1
- package/dist/gs/os/dir_unix.gs.js.map +1 -1
- package/dist/gs/os/error.gs.js +1 -1
- package/dist/gs/os/error.gs.js.map +1 -1
- package/dist/gs/os/exec.gs.d.ts +1 -0
- package/dist/gs/os/exec.gs.js +4 -8
- package/dist/gs/os/exec.gs.js.map +1 -1
- package/dist/gs/os/exec_posix.gs.js +1 -1
- package/dist/gs/os/exec_posix.gs.js.map +1 -1
- package/dist/gs/os/index.d.ts +1 -1
- package/dist/gs/os/index.js +1 -1
- package/dist/gs/os/index.js.map +1 -1
- package/dist/gs/os/proc.gs.d.ts +4 -0
- package/dist/gs/os/proc.gs.js +12 -6
- package/dist/gs/os/proc.gs.js.map +1 -1
- package/dist/gs/os/root_js.gs.js +1 -1
- package/dist/gs/os/root_js.gs.js.map +1 -1
- package/dist/gs/os/types.gs.js +1 -1
- package/dist/gs/os/types.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.d.ts +6 -2
- package/dist/gs/os/types_js.gs.js +170 -9
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/os/types_unix.gs.js +1 -1
- package/dist/gs/os/types_unix.gs.js.map +1 -1
- package/dist/gs/path/path.js +11 -7
- package/dist/gs/path/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +5 -4
- package/dist/gs/reflect/index.js +4 -3
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/map.js +15 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +26 -6
- package/dist/gs/reflect/type.js +1498 -279
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.d.ts +14 -6
- package/dist/gs/reflect/types.js +35 -1
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/value.d.ts +1 -0
- package/dist/gs/reflect/value.js +83 -41
- package/dist/gs/reflect/value.js.map +1 -1
- package/dist/gs/reflect/visiblefields.js +4 -140
- package/dist/gs/reflect/visiblefields.js.map +1 -1
- package/dist/gs/runtime/pprof/index.d.ts +8 -2
- package/dist/gs/runtime/pprof/index.js +50 -30
- package/dist/gs/runtime/pprof/index.js.map +1 -1
- package/dist/gs/runtime/runtime.js +5 -4
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/runtime/trace/index.js +5 -19
- package/dist/gs/runtime/trace/index.js.map +1 -1
- package/dist/gs/strconv/atoi.gs.js +1 -1
- package/dist/gs/strconv/atoi.gs.js.map +1 -1
- package/dist/gs/strconv/complex.gs.d.ts +3 -0
- package/dist/gs/strconv/complex.gs.js +148 -0
- package/dist/gs/strconv/complex.gs.js.map +1 -0
- package/dist/gs/strconv/index.d.ts +1 -0
- package/dist/gs/strconv/index.js +1 -0
- package/dist/gs/strconv/index.js.map +1 -1
- package/dist/gs/strings/builder.js +1 -1
- package/dist/gs/strings/reader.d.ts +1 -1
- package/dist/gs/strings/reader.js +11 -7
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/strings/replace.js +15 -7
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/strings/strings.d.ts +5 -0
- package/dist/gs/strings/strings.js +57 -5
- package/dist/gs/strings/strings.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.js +9 -9
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/atomic/value.gs.js +2 -2
- package/dist/gs/sync/atomic/value.gs.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +2 -1
- package/dist/gs/sync/sync.js +37 -16
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/env.js +22 -14
- package/dist/gs/syscall/env.js.map +1 -1
- package/dist/gs/syscall/js/index.js +9 -0
- package/dist/gs/syscall/js/index.js.map +1 -1
- package/dist/gs/testing/testing.js +59 -15
- package/dist/gs/testing/testing.js.map +1 -1
- package/dist/gs/time/time.d.ts +24 -1
- package/dist/gs/time/time.js +43 -3
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unique/index.js +7 -1
- package/dist/gs/unique/index.js.map +1 -1
- package/go.mod +3 -3
- package/go.sum +16 -0
- package/gs/builtin/builtin.ts +25 -2
- package/gs/builtin/runtime-contract.test.ts +260 -18
- package/gs/builtin/slice.ts +51 -4
- package/gs/builtin/type.ts +310 -63
- package/gs/builtin/varRef.ts +85 -2
- package/gs/bytes/buffer.gs.ts +1 -1
- package/gs/bytes/reader.gs.ts +1 -1
- package/gs/compress/zlib/index.test.ts +159 -1
- package/gs/compress/zlib/index.ts +164 -37
- package/gs/compress/zlib/meta.json +4 -1
- package/gs/compress/zlib/parity.json +51 -0
- package/gs/crypto/sha1/index.test.ts +19 -2
- package/gs/crypto/sha1/index.ts +3 -6
- package/gs/crypto/sha256/index.test.ts +14 -2
- package/gs/crypto/sha256/index.ts +3 -6
- package/gs/crypto/sha512/index.test.ts +17 -2
- package/gs/crypto/sha512/index.ts +3 -6
- package/gs/embed/index.test.ts +87 -0
- package/gs/embed/index.ts +229 -5
- package/gs/encoding/json/index.test.ts +360 -6
- package/gs/encoding/json/index.ts +679 -38
- package/gs/encoding/json/parity.json +81 -0
- package/gs/fmt/fmt.test.ts +41 -3
- package/gs/fmt/fmt.ts +40 -17
- package/gs/fmt/meta.json +6 -1
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +211 -3
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +857 -1
- package/gs/github.com/go-git/go-billy/v6/osfs/index.test.ts +110 -0
- package/gs/github.com/go-git/go-billy/v6/osfs/index.ts +280 -0
- package/gs/github.com/go-git/go-billy/v6/osfs/meta.json +8 -0
- package/gs/github.com/pkg/errors/errors.ts +54 -30
- package/gs/go/scanner/index.test.ts +39 -56
- package/gs/go/scanner/index.ts +33 -5
- package/gs/go/scanner/parity.json +27 -0
- package/gs/go/token/index.ts +22 -6
- package/gs/hash/index.test.ts +20 -33
- package/gs/hash/index.ts +28 -0
- package/gs/hash/parity.json +21 -0
- package/gs/internal/goarch/index.test.ts +32 -0
- package/gs/internal/goarch/index.ts +45 -13
- package/gs/internal/goarch/parity.json +144 -0
- package/gs/io/fs/fs.ts +26 -14
- package/gs/io/fs/readdir.test.ts +38 -0
- package/gs/io/fs/readdir.ts +8 -4
- package/gs/io/fs/sub.ts +8 -1
- package/gs/io/io.test.ts +77 -6
- package/gs/io/io.ts +115 -52
- package/gs/io/meta.json +7 -1
- package/gs/io/parity.json +162 -0
- package/gs/math/bits/index.test.ts +14 -1
- package/gs/math/bits/index.ts +75 -32
- package/gs/math/bits/parity.json +156 -0
- package/gs/mime/index.test.ts +90 -0
- package/gs/mime/index.ts +369 -6
- package/gs/mime/parity.json +36 -0
- package/gs/net/http/httptest/index.test.ts +98 -2
- package/gs/net/http/httptest/index.ts +101 -6
- package/gs/net/http/httptest/parity.json +15 -0
- package/gs/net/http/index.test.ts +797 -12
- package/gs/net/http/index.ts +1874 -136
- package/gs/net/http/meta.json +16 -1
- package/gs/net/http/parity.json +193 -0
- package/gs/os/dir_unix.gs.ts +1 -1
- package/gs/os/error.gs.ts +1 -1
- package/gs/os/exec.gs.ts +4 -8
- package/gs/os/exec_posix.gs.ts +1 -1
- package/gs/os/file_unix_js.test.ts +52 -0
- package/gs/os/index.test.ts +9 -0
- package/gs/os/index.ts +1 -0
- package/gs/os/meta.json +4 -0
- package/gs/os/parity.json +9 -0
- package/gs/os/proc.gs.ts +18 -5
- package/gs/os/proc.test.ts +26 -0
- package/gs/os/readdir.test.ts +56 -0
- package/gs/os/root_js.gs.ts +1 -1
- package/gs/os/types.gs.ts +1 -1
- package/gs/os/types_js.gs.ts +170 -9
- package/gs/os/types_unix.gs.ts +1 -1
- package/gs/path/path.ts +11 -7
- package/gs/reflect/deepequal.test.ts +10 -1
- package/gs/reflect/field.test.ts +37 -15
- package/gs/reflect/function-types.test.ts +518 -22
- package/gs/reflect/index.ts +8 -6
- package/gs/reflect/map.ts +20 -0
- package/gs/reflect/meta.json +6 -4
- package/gs/reflect/parity.json +234 -0
- package/gs/reflect/sliceat.test.ts +156 -0
- package/gs/reflect/structof.test.ts +401 -0
- package/gs/reflect/type.ts +1980 -365
- package/gs/reflect/typefor.test.ts +540 -10
- package/gs/reflect/types.ts +43 -18
- package/gs/reflect/value.ts +105 -45
- package/gs/reflect/visiblefields.ts +5 -168
- package/gs/runtime/parity.json +24 -0
- package/gs/runtime/pprof/index.test.ts +29 -7
- package/gs/runtime/pprof/index.ts +56 -30
- package/gs/runtime/pprof/parity.json +27 -0
- package/gs/runtime/runtime.test.ts +3 -1
- package/gs/runtime/runtime.ts +4 -3
- package/gs/runtime/trace/index.test.ts +5 -3
- package/gs/runtime/trace/index.ts +8 -20
- package/gs/runtime/trace/parity.json +36 -0
- package/gs/strconv/atoi.gs.ts +1 -1
- package/gs/strconv/complex.gs.ts +174 -0
- package/gs/strconv/complex.test.ts +65 -0
- package/gs/strconv/index.ts +1 -0
- package/gs/strconv/parity.json +120 -0
- package/gs/strings/builder.ts +1 -1
- package/gs/strings/meta.json +5 -2
- package/gs/strings/parity.json +186 -0
- package/gs/strings/reader.test.ts +2 -2
- package/gs/strings/reader.ts +11 -7
- package/gs/strings/replace.ts +15 -7
- package/gs/strings/strings.test.ts +22 -2
- package/gs/strings/strings.ts +64 -6
- package/gs/sync/atomic/type.gs.ts +9 -9
- package/gs/sync/atomic/value.gs.ts +2 -2
- package/gs/sync/meta.json +1 -0
- package/gs/sync/sync.test.ts +41 -1
- package/gs/sync/sync.ts +41 -16
- package/gs/syscall/env.ts +29 -14
- package/gs/syscall/js/index.test.ts +18 -0
- package/gs/syscall/js/index.ts +12 -0
- package/gs/testing/testing.test.ts +99 -3
- package/gs/testing/testing.ts +95 -24
- package/gs/time/parity.json +225 -0
- package/gs/time/time.test.ts +20 -2
- package/gs/time/time.ts +49 -7
- package/gs/unique/index.ts +7 -1
- package/package.json +4 -2
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -814
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -31
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1233
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
- /package/compiler/{wasm_api.go → wasm-api.go} +0 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto'
|
|
2
2
|
import { describe, expect, it } from 'vitest'
|
|
3
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
3
4
|
|
|
4
|
-
import { New, Sum } from './index.js'
|
|
5
|
+
import { New, Size, Sum } from './index.js'
|
|
5
6
|
|
|
6
7
|
describe('crypto/sha1 override', () => {
|
|
7
8
|
it('matches Node digest', async () => {
|
|
@@ -15,7 +16,23 @@ describe('crypto/sha1 override', () => {
|
|
|
15
16
|
h.Write(new TextEncoder().encode('go'))
|
|
16
17
|
h.Write(new TextEncoder().encode('script'))
|
|
17
18
|
|
|
18
|
-
expect(toHex(await h.Sum(null))).toBe(
|
|
19
|
+
expect(toHex(await h.Sum(null))).toBe(
|
|
20
|
+
nodeHash(new TextEncoder().encode('goscript')),
|
|
21
|
+
)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('appends into spare byte-slice backing', async () => {
|
|
25
|
+
const h = New()
|
|
26
|
+
h.Write(new TextEncoder().encode('abc'))
|
|
27
|
+
|
|
28
|
+
const backing = $.makeSlice<number>(Size, undefined, 'byte')
|
|
29
|
+
const out = await h.Sum($.goSlice(backing, 0, 0))
|
|
30
|
+
expect(out.length).toBe(Size)
|
|
31
|
+
expect(backing[0]).toBe(out[0])
|
|
32
|
+
expect(backing[Size - 1]).toBe(out[Size - 1])
|
|
33
|
+
expect(toHex($.bytesToUint8Array(backing))).toBe(
|
|
34
|
+
nodeHash(new TextEncoder().encode('abc')),
|
|
35
|
+
)
|
|
19
36
|
})
|
|
20
37
|
})
|
|
21
38
|
|
package/gs/crypto/sha1/index.ts
CHANGED
|
@@ -41,7 +41,7 @@ class Digest {
|
|
|
41
41
|
this.canCopyHash ?
|
|
42
42
|
new Uint8Array(this.hash!.copy!().digest())
|
|
43
43
|
: await sum(this.snapshotBytes())
|
|
44
|
-
return appendDigest(
|
|
44
|
+
return appendDigest(b, digest)
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
Reset(): void {
|
|
@@ -92,11 +92,8 @@ async function sum(data: $.Bytes): Promise<Uint8Array> {
|
|
|
92
92
|
return new Uint8Array(digest)
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
function appendDigest(prefix:
|
|
96
|
-
|
|
97
|
-
out.set(prefix)
|
|
98
|
-
out.set(digest, prefix.length)
|
|
99
|
-
return out
|
|
95
|
+
function appendDigest(prefix: $.Bytes, digest: Uint8Array): $.Bytes {
|
|
96
|
+
return $.append(prefix as any, ...digest) as $.Bytes
|
|
100
97
|
}
|
|
101
98
|
|
|
102
99
|
function createNodeHash(): NodeCryptoHash | null {
|
|
@@ -25,11 +25,23 @@ describe('crypto/sha256 override', () => {
|
|
|
25
25
|
)
|
|
26
26
|
})
|
|
27
27
|
|
|
28
|
+
test('streaming digest appends into spare byte-slice backing', async () => {
|
|
29
|
+
const digest = New()
|
|
30
|
+
expect(digest.Write($.stringToBytes('abc'))).toEqual([3, null])
|
|
31
|
+
|
|
32
|
+
const backing = $.makeSlice<number>(Size, undefined, 'byte')
|
|
33
|
+
const out = await digest.Sum($.goSlice(backing, 0, 0))
|
|
34
|
+
expect(out.length).toBe(Size)
|
|
35
|
+
expect(Array.from($.bytesToUint8Array(backing))).toEqual(
|
|
36
|
+
Array.from(await Sum256($.stringToBytes('abc'))),
|
|
37
|
+
)
|
|
38
|
+
})
|
|
39
|
+
|
|
28
40
|
test('sums SHA-224 with host crypto', async () => {
|
|
29
41
|
const sum = await Sum224($.stringToBytes('abc'))
|
|
30
42
|
expect(Array.from(sum)).toEqual([
|
|
31
|
-
35, 9, 125, 34, 52, 5, 216, 34, 134, 66, 164, 119, 189, 162, 85, 179,
|
|
32
|
-
|
|
43
|
+
35, 9, 125, 34, 52, 5, 216, 34, 134, 66, 164, 119, 189, 162, 85, 179, 42,
|
|
44
|
+
173, 188, 228, 189, 160, 179, 247, 227, 108, 157, 167,
|
|
33
45
|
])
|
|
34
46
|
})
|
|
35
47
|
|
|
@@ -44,7 +44,7 @@ class Digest {
|
|
|
44
44
|
this.canCopyHash ?
|
|
45
45
|
new Uint8Array(this.hash!.copy!().digest())
|
|
46
46
|
: await sum(this.algorithm, this.snapshotBytes())
|
|
47
|
-
return appendDigest(
|
|
47
|
+
return appendDigest(b, digest)
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
Reset(): void {
|
|
@@ -112,11 +112,8 @@ async function sum(
|
|
|
112
112
|
return new Uint8Array(digest)
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
function appendDigest(prefix:
|
|
116
|
-
|
|
117
|
-
out.set(prefix)
|
|
118
|
-
out.set(digest, prefix.length)
|
|
119
|
-
return out
|
|
115
|
+
function appendDigest(prefix: $.Bytes, digest: Uint8Array): $.Bytes {
|
|
116
|
+
return $.append(prefix as any, ...digest) as $.Bytes
|
|
120
117
|
}
|
|
121
118
|
|
|
122
119
|
function createNodeHash(algorithm: ShaAlgorithm): NodeCryptoHash | null {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto'
|
|
2
2
|
import { describe, expect, it } from 'vitest'
|
|
3
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
3
4
|
|
|
4
|
-
import { New, Sum384, Sum512, Sum512_224, Sum512_256 } from './index.js'
|
|
5
|
+
import { New, Size, Sum384, Sum512, Sum512_224, Sum512_256 } from './index.js'
|
|
5
6
|
|
|
6
7
|
describe('crypto/sha512 override', () => {
|
|
7
8
|
it('matches Node digests', async () => {
|
|
@@ -18,7 +19,21 @@ describe('crypto/sha512 override', () => {
|
|
|
18
19
|
h.Write(new TextEncoder().encode('go'))
|
|
19
20
|
h.Write(new TextEncoder().encode('script'))
|
|
20
21
|
|
|
21
|
-
expect(toHex(await h.Sum(null))).toBe(
|
|
22
|
+
expect(toHex(await h.Sum(null))).toBe(
|
|
23
|
+
nodeHash('sha512', new TextEncoder().encode('goscript')),
|
|
24
|
+
)
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
it('appends into spare byte-slice backing', async () => {
|
|
28
|
+
const h = New()
|
|
29
|
+
h.Write(new TextEncoder().encode('abc'))
|
|
30
|
+
|
|
31
|
+
const backing = $.makeSlice<number>(Size, undefined, 'byte')
|
|
32
|
+
const out = await h.Sum($.goSlice(backing, 0, 0))
|
|
33
|
+
expect(out.length).toBe(Size)
|
|
34
|
+
expect(toHex($.bytesToUint8Array(backing))).toBe(
|
|
35
|
+
nodeHash('sha512', new TextEncoder().encode('abc')),
|
|
36
|
+
)
|
|
22
37
|
})
|
|
23
38
|
})
|
|
24
39
|
|
|
@@ -38,7 +38,7 @@ class Digest {
|
|
|
38
38
|
this.canCopyHash ?
|
|
39
39
|
new Uint8Array(this.hash!.copy!().digest())
|
|
40
40
|
: await sum(this.algorithm, this.snapshotBytes())
|
|
41
|
-
return appendDigest(
|
|
41
|
+
return appendDigest(b, digest)
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
Reset(): void {
|
|
@@ -123,11 +123,8 @@ async function sum(
|
|
|
123
123
|
return new Uint8Array(digest)
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
function appendDigest(prefix:
|
|
127
|
-
|
|
128
|
-
out.set(prefix)
|
|
129
|
-
out.set(digest, prefix.length)
|
|
130
|
-
return out
|
|
126
|
+
function appendDigest(prefix: $.Bytes, digest: Uint8Array): $.Bytes {
|
|
127
|
+
return $.append(prefix as any, ...digest) as $.Bytes
|
|
131
128
|
}
|
|
132
129
|
|
|
133
130
|
function createNodeHash(algorithm: ShaAlgorithm): NodeCryptoHash | null {
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { cloneStructValue, markAsStructValue } from '@goscript/builtin/index.js'
|
|
4
|
+
import { EOF } from '@goscript/io/index.js'
|
|
5
|
+
import { ReadDir, ReadFile, Stat } from '@goscript/io/fs/index.js'
|
|
6
|
+
|
|
7
|
+
import { FS } from './index.js'
|
|
8
|
+
|
|
9
|
+
describe('embed.FS', () => {
|
|
10
|
+
it('clones embedded files as Go struct values', () => {
|
|
11
|
+
const original = markAsStructValue(
|
|
12
|
+
new FS(new Map([['config-set.bin', new Uint8Array([1, 2, 3])]])),
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
const cloned = cloneStructValue(original)
|
|
16
|
+
const [data, err] = cloned.ReadFile('config-set.bin')
|
|
17
|
+
|
|
18
|
+
expect(err).toBeNull()
|
|
19
|
+
expect(Array.from(data)).toEqual([1, 2, 3])
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('supports io/fs read, stat, and directory APIs', () => {
|
|
23
|
+
const fsys = markAsStructValue(
|
|
24
|
+
new FS(
|
|
25
|
+
new Map([
|
|
26
|
+
['config-set.bin', new Uint8Array([1, 2, 3])],
|
|
27
|
+
['assets/config.json', new Uint8Array([4])],
|
|
28
|
+
]),
|
|
29
|
+
),
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
const [data, readErr] = ReadFile(fsys, 'config-set.bin')
|
|
33
|
+
expect(readErr).toBeNull()
|
|
34
|
+
expect(Array.from(data)).toEqual([1, 2, 3])
|
|
35
|
+
data[0] = 9
|
|
36
|
+
const [dataAgain, readAgainErr] = ReadFile(fsys, 'config-set.bin')
|
|
37
|
+
expect(readAgainErr).toBeNull()
|
|
38
|
+
expect(Array.from(dataAgain)).toEqual([1, 2, 3])
|
|
39
|
+
|
|
40
|
+
const [rootEntries, rootErr] = ReadDir(fsys, '.')
|
|
41
|
+
expect(rootErr).toBeNull()
|
|
42
|
+
expect(rootEntries!.map((entry) => entry!.Name())).toEqual([
|
|
43
|
+
'assets',
|
|
44
|
+
'config-set.bin',
|
|
45
|
+
])
|
|
46
|
+
|
|
47
|
+
const [assetInfo, statErr] = Stat(fsys, 'assets')
|
|
48
|
+
expect(statErr).toBeNull()
|
|
49
|
+
expect(assetInfo!.IsDir()).toBe(true)
|
|
50
|
+
|
|
51
|
+
const [assetEntries, assetErr] = ReadDir(fsys, 'assets')
|
|
52
|
+
expect(assetErr).toBeNull()
|
|
53
|
+
expect(assetEntries!.map((entry) => entry!.Name())).toEqual(['config.json'])
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('supports Open file reads and directory iteration', () => {
|
|
57
|
+
const fsys = markAsStructValue(
|
|
58
|
+
new FS(
|
|
59
|
+
new Map([
|
|
60
|
+
['config-set.bin', new Uint8Array([1, 2, 3])],
|
|
61
|
+
['assets/config.json', new Uint8Array([4])],
|
|
62
|
+
]),
|
|
63
|
+
),
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
const [file, openErr] = fsys.Open('config-set.bin')
|
|
67
|
+
expect(openErr).toBeNull()
|
|
68
|
+
const buffer = new Uint8Array(2)
|
|
69
|
+
const [firstRead, firstErr] = file!.Read(buffer)
|
|
70
|
+
expect(firstErr).toBeNull()
|
|
71
|
+
expect(firstRead).toBe(2)
|
|
72
|
+
expect(Array.from(buffer)).toEqual([1, 2])
|
|
73
|
+
const [secondRead, secondErr] = file!.Read(buffer)
|
|
74
|
+
expect(secondErr).toBeNull()
|
|
75
|
+
expect(secondRead).toBe(1)
|
|
76
|
+
expect(Array.from(buffer)).toEqual([3, 2])
|
|
77
|
+
const [eofRead, eofErr] = file!.Read(buffer)
|
|
78
|
+
expect(eofRead).toBe(0)
|
|
79
|
+
expect(eofErr).toBe(EOF)
|
|
80
|
+
|
|
81
|
+
const [dir, dirOpenErr] = fsys.Open('.')
|
|
82
|
+
expect(dirOpenErr).toBeNull()
|
|
83
|
+
const [entries, readDirErr] = dir!.ReadDir(1)
|
|
84
|
+
expect(readDirErr).toBeNull()
|
|
85
|
+
expect(entries!.map((entry) => entry!.Name())).toEqual(['assets'])
|
|
86
|
+
})
|
|
87
|
+
})
|
package/gs/embed/index.ts
CHANGED
|
@@ -1,20 +1,244 @@
|
|
|
1
1
|
import * as $ from '@goscript/builtin/index.js'
|
|
2
|
+
import * as io from '@goscript/io/index.js'
|
|
2
3
|
import * as fs from '@goscript/io/fs/index.js'
|
|
4
|
+
import * as time from '@goscript/time/index.js'
|
|
3
5
|
|
|
4
6
|
export class FS {
|
|
7
|
+
private files: Map<string, Uint8Array>
|
|
8
|
+
|
|
9
|
+
constructor(files?: Map<string, Uint8Array>) {
|
|
10
|
+
this.files = files ?? new Map()
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
clone(): FS {
|
|
14
|
+
const files = new Map<string, Uint8Array>()
|
|
15
|
+
for (const [name, data] of this.files) {
|
|
16
|
+
files.set(name, data.slice())
|
|
17
|
+
}
|
|
18
|
+
return $.markAsStructValue(new FS(files))
|
|
19
|
+
}
|
|
20
|
+
|
|
5
21
|
Open(name: string): [fs.File, $.GoError] {
|
|
6
|
-
|
|
22
|
+
const err = validatePath('open', name)
|
|
23
|
+
if (err != null) {
|
|
24
|
+
return [null, err]
|
|
25
|
+
}
|
|
26
|
+
const data = this.files.get(name)
|
|
27
|
+
if (data !== undefined) {
|
|
28
|
+
return [new embedFile(name, data), null]
|
|
29
|
+
}
|
|
30
|
+
const entries = this.dirEntries(name)
|
|
31
|
+
if (entries === null) {
|
|
32
|
+
return [null, pathError('open', name, fs.ErrNotExist)]
|
|
33
|
+
}
|
|
34
|
+
return [new embedFile(name, null, entries), null]
|
|
7
35
|
}
|
|
8
36
|
|
|
9
37
|
ReadDir(name: string): [$.Slice<fs.DirEntry>, $.GoError] {
|
|
10
|
-
|
|
38
|
+
const err = validatePath('read', name)
|
|
39
|
+
if (err != null) {
|
|
40
|
+
return [null, err]
|
|
41
|
+
}
|
|
42
|
+
const entries = this.dirEntries(name)
|
|
43
|
+
if (entries === null) {
|
|
44
|
+
return [null, pathError('read', name, fs.ErrNotExist)]
|
|
45
|
+
}
|
|
46
|
+
return [entries, null]
|
|
11
47
|
}
|
|
12
48
|
|
|
13
49
|
ReadFile(name: string): [Uint8Array, $.GoError] {
|
|
14
|
-
|
|
50
|
+
const err = validatePath('read', name)
|
|
51
|
+
if (err != null) {
|
|
52
|
+
return [new Uint8Array(0), err]
|
|
53
|
+
}
|
|
54
|
+
const data = this.files.get(name)
|
|
55
|
+
if (data === undefined) {
|
|
56
|
+
const err = this.dirExists(name) ? fs.ErrInvalid : fs.ErrNotExist
|
|
57
|
+
return [new Uint8Array(0), pathError('read', name, err)]
|
|
58
|
+
}
|
|
59
|
+
return [data.slice(), null]
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
Stat(name: string): [fs.FileInfo, $.GoError] {
|
|
63
|
+
const err = validatePath('stat', name)
|
|
64
|
+
if (err != null) {
|
|
65
|
+
return [null, err]
|
|
66
|
+
}
|
|
67
|
+
const data = this.files.get(name)
|
|
68
|
+
if (data !== undefined) {
|
|
69
|
+
return [new embedFileInfo(baseName(name), data.byteLength, 0o444), null]
|
|
70
|
+
}
|
|
71
|
+
if (!this.dirExists(name)) {
|
|
72
|
+
return [null, pathError('stat', name, fs.ErrNotExist)]
|
|
73
|
+
}
|
|
74
|
+
return [new embedFileInfo(baseName(name), 0, fs.ModeDir | 0o555), null]
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private dirEntries(name: string): $.Slice<fs.DirEntry> | null {
|
|
78
|
+
if (!this.dirExists(name)) {
|
|
79
|
+
return null
|
|
80
|
+
}
|
|
81
|
+
const prefix = name === '.' ? '' : name + '/'
|
|
82
|
+
const entries = new Map<string, fs.DirEntry>()
|
|
83
|
+
for (const [filePath, data] of this.files) {
|
|
84
|
+
if (prefix !== '' && !filePath.startsWith(prefix)) {
|
|
85
|
+
continue
|
|
86
|
+
}
|
|
87
|
+
const rest = prefix === '' ? filePath : filePath.slice(prefix.length)
|
|
88
|
+
if (rest === '') {
|
|
89
|
+
continue
|
|
90
|
+
}
|
|
91
|
+
const slash = rest.indexOf('/')
|
|
92
|
+
const childName = slash === -1 ? rest : rest.slice(0, slash)
|
|
93
|
+
if (entries.has(childName)) {
|
|
94
|
+
continue
|
|
95
|
+
}
|
|
96
|
+
const isDir = slash !== -1
|
|
97
|
+
const info =
|
|
98
|
+
isDir ?
|
|
99
|
+
new embedFileInfo(childName, 0, fs.ModeDir | 0o555)
|
|
100
|
+
: new embedFileInfo(childName, data.byteLength, 0o444)
|
|
101
|
+
entries.set(childName, new embedDirEntry(info))
|
|
102
|
+
}
|
|
103
|
+
return Array.from(entries.values()).sort((a, b) =>
|
|
104
|
+
a!.Name().localeCompare(b!.Name()),
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private dirExists(name: string): boolean {
|
|
109
|
+
if (name === '.') {
|
|
110
|
+
return true
|
|
111
|
+
}
|
|
112
|
+
const prefix = name + '/'
|
|
113
|
+
for (const path of this.files.keys()) {
|
|
114
|
+
if (path.startsWith(prefix)) {
|
|
115
|
+
return true
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return false
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
class embedFile {
|
|
123
|
+
private offset = 0
|
|
124
|
+
private dirOffset = 0
|
|
125
|
+
|
|
126
|
+
constructor(
|
|
127
|
+
private readonly name: string,
|
|
128
|
+
private readonly data: Uint8Array | null,
|
|
129
|
+
private readonly entries: $.Slice<fs.DirEntry> = [],
|
|
130
|
+
) {}
|
|
131
|
+
|
|
132
|
+
Close(): $.GoError {
|
|
133
|
+
return null
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
Read(buffer: Uint8Array): [number, $.GoError] {
|
|
137
|
+
if (this.data === null) {
|
|
138
|
+
return [0, pathError('read', this.name, fs.ErrInvalid)]
|
|
139
|
+
}
|
|
140
|
+
if (this.offset >= this.data.byteLength) {
|
|
141
|
+
return [0, io.EOF]
|
|
142
|
+
}
|
|
143
|
+
const n = Math.min(buffer.byteLength, this.data.byteLength - this.offset)
|
|
144
|
+
buffer.set(this.data.subarray(this.offset, this.offset + n))
|
|
145
|
+
this.offset += n
|
|
146
|
+
return [n, null]
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
ReadDir(n: number): [$.Slice<fs.DirEntry>, $.GoError] {
|
|
150
|
+
if (this.data !== null) {
|
|
151
|
+
return [null, pathError('readdir', this.name, fs.ErrInvalid)]
|
|
152
|
+
}
|
|
153
|
+
const allEntries = this.entries ?? []
|
|
154
|
+
if (n <= 0) {
|
|
155
|
+
const entries = allEntries.slice(this.dirOffset)
|
|
156
|
+
this.dirOffset = allEntries.length
|
|
157
|
+
return [entries, null]
|
|
158
|
+
}
|
|
159
|
+
if (this.dirOffset >= allEntries.length) {
|
|
160
|
+
return [[], io.EOF]
|
|
161
|
+
}
|
|
162
|
+
const entries = allEntries.slice(this.dirOffset, this.dirOffset + n)
|
|
163
|
+
this.dirOffset += entries.length
|
|
164
|
+
return [entries, null]
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
Stat(): [fs.FileInfo, $.GoError] {
|
|
168
|
+
if (this.data === null) {
|
|
169
|
+
return [new embedFileInfo(baseName(this.name), 0, fs.ModeDir | 0o555), null]
|
|
170
|
+
}
|
|
171
|
+
return [new embedFileInfo(baseName(this.name), this.data.byteLength, 0o444), null]
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
class embedFileInfo {
|
|
176
|
+
constructor(
|
|
177
|
+
private readonly name: string,
|
|
178
|
+
private readonly size: number,
|
|
179
|
+
private readonly mode: fs.FileMode,
|
|
180
|
+
) {}
|
|
181
|
+
|
|
182
|
+
IsDir(): boolean {
|
|
183
|
+
return fs.FileMode_IsDir(this.mode)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
ModTime(): time.Time {
|
|
187
|
+
return new time.Time()
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
Mode(): fs.FileMode {
|
|
191
|
+
return this.mode
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
Name(): string {
|
|
195
|
+
return this.name
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
Size(): number {
|
|
199
|
+
return this.size
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
Sys(): null {
|
|
203
|
+
return null
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
class embedDirEntry {
|
|
208
|
+
constructor(private readonly info: fs.FileInfo) {}
|
|
209
|
+
|
|
210
|
+
Info(): [fs.FileInfo, $.GoError] {
|
|
211
|
+
return [this.info, null]
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
IsDir(): boolean {
|
|
215
|
+
return this.info!.IsDir()
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
Name(): string {
|
|
219
|
+
return this.info!.Name()
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
Type(): fs.FileMode {
|
|
223
|
+
return fs.fileModeType(this.info!.Mode())
|
|
15
224
|
}
|
|
16
225
|
}
|
|
17
226
|
|
|
18
|
-
function
|
|
19
|
-
|
|
227
|
+
function validatePath(op: string, name: string): $.GoError {
|
|
228
|
+
if (!fs.ValidPath(name)) {
|
|
229
|
+
return pathError(op, name, fs.ErrInvalid)
|
|
230
|
+
}
|
|
231
|
+
return null
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function pathError(op: string, name: string, err: $.GoError): $.GoError {
|
|
235
|
+
return new fs.PathError({ Op: op, Path: name, Err: err })
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function baseName(name: string): string {
|
|
239
|
+
const idx = name.lastIndexOf('/')
|
|
240
|
+
if (idx === -1) {
|
|
241
|
+
return name
|
|
242
|
+
}
|
|
243
|
+
return name.slice(idx + 1)
|
|
20
244
|
}
|