goscript 0.2.3 → 0.2.5
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 +8 -8
- package/cmd/go_js_wasm_exec/main.go +1 -1
- package/cmd/go_js_wasm_exec/main_test.go +1 -1
- package/cmd/goscript/cmd-compile.go +9 -1
- package/cmd/goscript/cmd-test.go +1 -1
- package/cmd/goscript/cmd_compile_test.go +44 -0
- package/cmd/goscript/deps.go +1 -1
- package/cmd/goscript-wasm/main.go +2 -2
- package/compiler/compile-request.go +19 -0
- package/compiler/compile_bench_test.go +121 -0
- package/compiler/compliance_test.go +17 -1
- package/compiler/config.go +2 -0
- package/compiler/gotest/result.go +1 -1
- package/compiler/gotest/runner.go +2 -2
- package/compiler/gotest/runner_test.go +4 -7
- package/compiler/index.test.ts +28 -0
- package/compiler/index.ts +32 -16
- package/compiler/lowering.go +1236 -143
- package/compiler/lowering_bench_test.go +4 -0
- package/compiler/override-facts.go +1 -1
- package/compiler/override-registry_test.go +125 -0
- package/compiler/package-graph.go +92 -0
- package/compiler/package-graph_test.go +113 -0
- package/compiler/runtime-contract.go +1 -1
- package/compiler/semantic-model.go +32 -0
- package/compiler/skeleton_test.go +284 -11
- package/compiler/wasm/compile.go +1 -1
- package/compiler/wasm/compile_test.go +1 -1
- package/dist/compiler/index.d.ts +4 -0
- package/dist/compiler/index.js +26 -15
- package/dist/compiler/index.js.map +1 -1
- package/dist/gs/compress/gzip/index.d.ts +41 -0
- package/dist/gs/compress/gzip/index.js +235 -0
- package/dist/gs/compress/gzip/index.js.map +1 -0
- package/dist/gs/database/sql/driver/index.d.ts +165 -0
- package/dist/gs/database/sql/driver/index.js +432 -0
- package/dist/gs/database/sql/driver/index.js.map +1 -0
- package/dist/gs/encoding/binary/index.d.ts +71 -0
- package/dist/gs/encoding/binary/index.js +778 -0
- package/dist/gs/encoding/binary/index.js.map +1 -0
- package/dist/gs/fmt/fmt.js +156 -57
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/klauspost/cpuid/v2/index.d.ts +11 -0
- package/dist/gs/github.com/klauspost/cpuid/v2/index.js +28 -0
- package/dist/gs/github.com/klauspost/cpuid/v2/index.js.map +1 -0
- package/dist/gs/github.com/pkg/errors/errors.d.ts +0 -2
- package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/index.d.ts +2 -1
- package/dist/gs/github.com/pkg/errors/index.js +1 -1
- package/dist/gs/github.com/pkg/errors/index.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/stack.d.ts +8 -19
- package/dist/gs/github.com/pkg/errors/stack.js +26 -61
- package/dist/gs/github.com/pkg/errors/stack.js.map +1 -1
- package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.d.ts +19 -0
- package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.js +25 -0
- package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.js.map +1 -0
- package/dist/gs/golang.org/x/crypto/cryptobyte/index.d.ts +104 -0
- package/dist/gs/golang.org/x/crypto/cryptobyte/index.js +1107 -0
- package/dist/gs/golang.org/x/crypto/cryptobyte/index.js.map +1 -0
- package/dist/gs/golang.org/x/crypto/internal/alias/index.d.ts +3 -0
- package/dist/gs/golang.org/x/crypto/internal/alias/index.js +39 -0
- package/dist/gs/golang.org/x/crypto/internal/alias/index.js.map +1 -0
- package/dist/gs/io/fs/glob.js +1 -1
- package/dist/gs/io/fs/glob.js.map +1 -1
- package/dist/gs/io/fs/readlink.d.ts +1 -1
- package/dist/gs/io/fs/readlink.js +2 -2
- package/dist/gs/io/fs/readlink.js.map +1 -1
- package/dist/gs/io/fs/stat.d.ts +4 -2
- package/dist/gs/io/fs/stat.js +12 -73
- package/dist/gs/io/fs/stat.js.map +1 -1
- package/dist/gs/io/fs/sub.d.ts +2 -2
- package/dist/gs/io/fs/sub.js +7 -7
- package/dist/gs/io/fs/sub.js.map +1 -1
- package/dist/gs/io/fs/walk.js +1 -1
- package/dist/gs/io/fs/walk.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +18 -14
- package/dist/gs/net/http/index.js +44 -23
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/net/http/pprof/index.d.ts +5 -5
- package/dist/gs/net/http/pprof/index.js +21 -21
- package/dist/gs/net/http/pprof/index.js.map +1 -1
- package/dist/gs/runtime/runtime.d.ts +6 -1
- package/dist/gs/runtime/runtime.js +15 -8
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/runtime/trace/index.d.ts +8 -5
- package/dist/gs/runtime/trace/index.js +324 -23
- package/dist/gs/runtime/trace/index.js.map +1 -1
- package/dist/gs/slices/slices.d.ts +2 -1
- package/dist/gs/slices/slices.js +9 -3
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/sort/search.gs.d.ts +3 -1
- package/dist/gs/sort/search.gs.js +18 -53
- package/dist/gs/sort/search.gs.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +1 -1
- package/dist/gs/sync/sync.js +3 -0
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/time/time.d.ts +22 -29
- package/dist/gs/time/time.js +111 -32
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unsafe/unsafe.d.ts +3 -2
- package/dist/gs/unsafe/unsafe.js.map +1 -1
- package/go.mod +7 -5
- package/go.sum +12 -26
- package/gs/builtin/runtime-contract.test.ts +25 -0
- package/gs/compress/gzip/index.test.ts +86 -0
- package/gs/compress/gzip/index.ts +297 -0
- package/gs/compress/gzip/meta.json +6 -0
- package/gs/compress/gzip/parity.json +45 -0
- package/gs/database/sql/driver/index.test.ts +88 -0
- package/gs/database/sql/driver/index.ts +675 -0
- package/gs/database/sql/driver/meta.json +3 -0
- package/gs/database/sql/driver/parity.json +144 -0
- package/gs/embed/index.test.ts +1 -1
- package/gs/encoding/binary/index.test.ts +239 -0
- package/gs/encoding/binary/index.ts +999 -0
- package/gs/encoding/binary/meta.json +9 -0
- package/gs/encoding/binary/parity.json +72 -0
- package/gs/fmt/fmt.test.ts +28 -0
- package/gs/fmt/fmt.ts +198 -61
- package/gs/fmt/meta.json +2 -1
- package/gs/github.com/klauspost/cpuid/v2/index.ts +38 -0
- package/gs/github.com/klauspost/cpuid/v2/meta.json +3 -0
- package/gs/github.com/pkg/errors/errors.ts +1 -2
- package/gs/github.com/pkg/errors/index.ts +2 -1
- package/gs/github.com/pkg/errors/stack.ts +34 -62
- package/gs/golang.org/x/crypto/cryptobyte/asn1/index.test.ts +19 -0
- package/gs/golang.org/x/crypto/cryptobyte/asn1/index.ts +29 -0
- package/gs/golang.org/x/crypto/cryptobyte/index.test.ts +255 -0
- package/gs/golang.org/x/crypto/cryptobyte/index.ts +1441 -0
- package/gs/golang.org/x/crypto/cryptobyte/meta.json +3 -0
- package/gs/golang.org/x/crypto/internal/alias/index.test.ts +40 -0
- package/gs/golang.org/x/crypto/internal/alias/index.ts +40 -0
- package/gs/io/fs/glob.ts +1 -1
- package/gs/io/fs/meta.json +3 -0
- package/gs/io/fs/readlink.test.ts +2 -2
- package/gs/io/fs/readlink.ts +5 -2
- package/gs/io/fs/stat.test.ts +79 -0
- package/gs/io/fs/stat.ts +24 -10
- package/gs/io/fs/sub.test.ts +93 -0
- package/gs/io/fs/sub.ts +9 -9
- package/gs/io/fs/walk.ts +1 -1
- package/gs/net/http/index.test.ts +207 -2
- package/gs/net/http/index.ts +68 -37
- package/gs/net/http/meta.json +3 -1
- package/gs/net/http/pprof/index.test.ts +4 -4
- package/gs/net/http/pprof/index.ts +30 -27
- package/gs/runtime/runtime.test.ts +16 -0
- package/gs/runtime/runtime.ts +17 -9
- package/gs/runtime/trace/index.test.ts +113 -14
- package/gs/runtime/trace/index.ts +384 -34
- package/gs/runtime/trace/meta.json +1 -0
- package/gs/slices/slices.test.ts +24 -1
- package/gs/slices/slices.ts +14 -4
- package/gs/sort/meta.json +1 -0
- package/gs/sort/search.gs.ts +20 -5
- package/gs/sync/sync.ts +4 -1
- package/gs/time/time.test.ts +79 -2
- package/gs/time/time.ts +133 -33
- package/gs/unsafe/unsafe.ts +4 -2
- package/package.json +2 -2
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
2
|
+
import * as errors from '@goscript/errors/index.js'
|
|
3
|
+
import * as io from '@goscript/io/index.js'
|
|
4
|
+
|
|
5
|
+
type maybeAsyncWriter = {
|
|
6
|
+
Write(p: $.Bytes): [number, $.GoError] | Promise<[number, $.GoError]>
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type compressionRuntime = {
|
|
10
|
+
gzipSync?: (data: Uint8Array, opts?: Record<string, unknown>) => Uint8Array
|
|
11
|
+
gunzipSync?: (data: Uint8Array) => Uint8Array
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const NoCompression = 0
|
|
15
|
+
export const BestSpeed = 1
|
|
16
|
+
export const BestCompression = 9
|
|
17
|
+
export const DefaultCompression = -1
|
|
18
|
+
export const HuffmanOnly = -2
|
|
19
|
+
|
|
20
|
+
export let ErrChecksum = errors.New('gzip: invalid checksum')
|
|
21
|
+
export let ErrHeader = errors.New('gzip: invalid header')
|
|
22
|
+
|
|
23
|
+
export function __goscript_set_ErrChecksum(value: $.GoError): void {
|
|
24
|
+
ErrChecksum = value
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function __goscript_set_ErrHeader(value: $.GoError): void {
|
|
28
|
+
ErrHeader = value
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class Header {
|
|
32
|
+
Comment = ''
|
|
33
|
+
Extra: $.Bytes = null
|
|
34
|
+
ModTime: any = null
|
|
35
|
+
Name = ''
|
|
36
|
+
OS = 255
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export class Reader {
|
|
40
|
+
private data: Uint8Array = new Uint8Array(0)
|
|
41
|
+
private offset = 0
|
|
42
|
+
private pending: Promise<{ data: Uint8Array | null; err: $.GoError }> | null =
|
|
43
|
+
null
|
|
44
|
+
|
|
45
|
+
constructor(r?: io.Reader | null) {
|
|
46
|
+
if (r != null) {
|
|
47
|
+
this.Reset(r)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async Read(p: $.Bytes): Promise<[number, $.GoError]> {
|
|
52
|
+
const pending = this.pending
|
|
53
|
+
if (pending != null) {
|
|
54
|
+
this.pending = null
|
|
55
|
+
const result = await pending
|
|
56
|
+
if (result.err != null) {
|
|
57
|
+
return [0, result.err]
|
|
58
|
+
}
|
|
59
|
+
this.data = result.data ?? new Uint8Array(0)
|
|
60
|
+
this.offset = 0
|
|
61
|
+
}
|
|
62
|
+
if (this.offset >= this.data.length) {
|
|
63
|
+
return [0, io.EOF]
|
|
64
|
+
}
|
|
65
|
+
const out = $.bytesToUint8Array(p)
|
|
66
|
+
const n = Math.min(out.length, this.data.length - this.offset)
|
|
67
|
+
out.set(this.data.subarray(this.offset, this.offset + n))
|
|
68
|
+
this.offset += n
|
|
69
|
+
return [n, null]
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
Close(): $.GoError {
|
|
73
|
+
return null
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
Reset(r: io.Reader | null): $.GoError {
|
|
77
|
+
if (r == null) {
|
|
78
|
+
return errors.New('gzip: nil reader')
|
|
79
|
+
}
|
|
80
|
+
const result = readGunzipped(r)
|
|
81
|
+
this.data = new Uint8Array(0)
|
|
82
|
+
this.offset = 0
|
|
83
|
+
if (result instanceof Promise) {
|
|
84
|
+
this.pending = result
|
|
85
|
+
return null
|
|
86
|
+
}
|
|
87
|
+
this.pending = null
|
|
88
|
+
if (result.err != null) {
|
|
89
|
+
return result.err
|
|
90
|
+
}
|
|
91
|
+
this.data = result.data ?? new Uint8Array(0)
|
|
92
|
+
return null
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export class Writer {
|
|
97
|
+
private chunks: Uint8Array[] = []
|
|
98
|
+
private closed = false
|
|
99
|
+
|
|
100
|
+
constructor(
|
|
101
|
+
private w: io.Writer | null,
|
|
102
|
+
private level = DefaultCompression,
|
|
103
|
+
) {}
|
|
104
|
+
|
|
105
|
+
Write(p: $.Bytes): [number, $.GoError] {
|
|
106
|
+
if (this.closed) {
|
|
107
|
+
return [0, errors.New('gzip: writer closed')]
|
|
108
|
+
}
|
|
109
|
+
const data = $.bytesToUint8Array(p)
|
|
110
|
+
this.chunks.push(data.slice())
|
|
111
|
+
return [data.length, null]
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async Close(): Promise<$.GoError> {
|
|
115
|
+
if (this.closed) {
|
|
116
|
+
return null
|
|
117
|
+
}
|
|
118
|
+
this.closed = true
|
|
119
|
+
if (this.w == null) {
|
|
120
|
+
return errors.New('gzip: nil writer')
|
|
121
|
+
}
|
|
122
|
+
const compressed = await gzipBytes(concat(this.chunks), this.level)
|
|
123
|
+
const writer = $.pointerValue<maybeAsyncWriter>(this.w)
|
|
124
|
+
const [, err] = await writer.Write(compressed)
|
|
125
|
+
return err
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
Flush(): $.GoError {
|
|
129
|
+
return null
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
Reset(w: io.Writer | null): void {
|
|
133
|
+
this.w = w
|
|
134
|
+
this.chunks = []
|
|
135
|
+
this.closed = false
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export function NewReader(
|
|
140
|
+
r: io.Reader | null,
|
|
141
|
+
): [io.ReadCloser | null, $.GoError] {
|
|
142
|
+
const reader = new Reader()
|
|
143
|
+
const err = reader.Reset(r)
|
|
144
|
+
if (err != null) {
|
|
145
|
+
return [null, err]
|
|
146
|
+
}
|
|
147
|
+
return [reader as any, null]
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function NewWriter(w: io.Writer | null): Writer {
|
|
151
|
+
return new Writer(w)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export function NewWriterLevel(
|
|
155
|
+
w: io.Writer | null,
|
|
156
|
+
level: number,
|
|
157
|
+
): [Writer | null, $.GoError] {
|
|
158
|
+
if (level < HuffmanOnly || level > BestCompression) {
|
|
159
|
+
return [null, errors.New(`gzip: invalid compression level: ${level}`)]
|
|
160
|
+
}
|
|
161
|
+
return [new Writer(w, level), null]
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
async function gzipBytes(data: Uint8Array, level: number): Promise<Uint8Array> {
|
|
165
|
+
const runtime = nodeCompressionRuntime()
|
|
166
|
+
if (runtime?.gzipSync != null) {
|
|
167
|
+
return runtime.gzipSync(data, { level })
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const CompressionStreamCtor = (globalThis as any).CompressionStream
|
|
171
|
+
if (typeof CompressionStreamCtor !== 'function') {
|
|
172
|
+
throw new Error('compress/gzip: CompressionStream unavailable')
|
|
173
|
+
}
|
|
174
|
+
return streamTransform(data, new CompressionStreamCtor('gzip'))
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function gunzipBytes(
|
|
178
|
+
data: Uint8Array,
|
|
179
|
+
): Uint8Array | Promise<Uint8Array> {
|
|
180
|
+
const runtime = nodeCompressionRuntime()
|
|
181
|
+
if (runtime?.gunzipSync != null) {
|
|
182
|
+
return runtime.gunzipSync(data)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const DecompressionStreamCtor = (globalThis as any).DecompressionStream
|
|
186
|
+
if (typeof DecompressionStreamCtor !== 'function') {
|
|
187
|
+
throw new Error('compress/gzip: DecompressionStream unavailable')
|
|
188
|
+
}
|
|
189
|
+
return streamTransform(data, new DecompressionStreamCtor('gzip'))
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
async function streamTransform(
|
|
193
|
+
data: Uint8Array,
|
|
194
|
+
stream: ReadableWritablePair<Uint8Array, Uint8Array>,
|
|
195
|
+
): Promise<Uint8Array> {
|
|
196
|
+
const body = new ArrayBuffer(data.length)
|
|
197
|
+
new Uint8Array(body).set(data)
|
|
198
|
+
const response = new Response(
|
|
199
|
+
new Blob([body]).stream().pipeThrough(stream as any),
|
|
200
|
+
)
|
|
201
|
+
return new Uint8Array(await response.arrayBuffer())
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function readGunzipped(
|
|
205
|
+
r: io.Reader,
|
|
206
|
+
):
|
|
207
|
+
| { data: Uint8Array | null; err: $.GoError }
|
|
208
|
+
| Promise<{ data: Uint8Array | null; err: $.GoError }> {
|
|
209
|
+
const chunks: Uint8Array[] = []
|
|
210
|
+
const buf = $.makeSlice<number>(1, undefined, 'byte')
|
|
211
|
+
while (true) {
|
|
212
|
+
const read = r.Read(buf)
|
|
213
|
+
if (read instanceof Promise) {
|
|
214
|
+
return readGunzippedAsync(read, r, buf, chunks)
|
|
215
|
+
}
|
|
216
|
+
const [n, err] = read
|
|
217
|
+
recordChunk(chunks, buf, n)
|
|
218
|
+
if (err != null) {
|
|
219
|
+
if (err === io.EOF) {
|
|
220
|
+
return inflateRecorded(chunks)
|
|
221
|
+
}
|
|
222
|
+
return { data: null, err }
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async function readGunzippedAsync(
|
|
228
|
+
read: Promise<[number, $.GoError]>,
|
|
229
|
+
r: io.Reader,
|
|
230
|
+
buf: $.Bytes,
|
|
231
|
+
chunks: Uint8Array[],
|
|
232
|
+
): Promise<{ data: Uint8Array | null; err: $.GoError }> {
|
|
233
|
+
while (true) {
|
|
234
|
+
const [n, err] = await read
|
|
235
|
+
recordChunk(chunks, buf, n)
|
|
236
|
+
if (err != null) {
|
|
237
|
+
if (err === io.EOF) {
|
|
238
|
+
return inflateRecorded(chunks)
|
|
239
|
+
}
|
|
240
|
+
return { data: null, err }
|
|
241
|
+
}
|
|
242
|
+
read = r.Read(buf) as any
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function recordChunk(chunks: Uint8Array[], buf: $.Bytes, n: number): void {
|
|
247
|
+
if (n > 0) {
|
|
248
|
+
chunks.push($.bytesToUint8Array($.goSlice(buf, 0, n)).slice())
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function inflateRecorded(
|
|
253
|
+
chunks: Uint8Array[],
|
|
254
|
+
): { data: Uint8Array | null; err: $.GoError } | Promise<{
|
|
255
|
+
data: Uint8Array | null
|
|
256
|
+
err: $.GoError
|
|
257
|
+
}> {
|
|
258
|
+
try {
|
|
259
|
+
const inflated = gunzipBytes(concat(chunks))
|
|
260
|
+
if (inflated instanceof Promise) {
|
|
261
|
+
return inflated
|
|
262
|
+
.then((data) => ({ data, err: null }))
|
|
263
|
+
.catch(() => ({ data: null, err: ErrHeader }))
|
|
264
|
+
}
|
|
265
|
+
return { data: inflated, err: null }
|
|
266
|
+
} catch {
|
|
267
|
+
return { data: null, err: ErrHeader }
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function concat(chunks: Uint8Array[]): Uint8Array {
|
|
272
|
+
let length = 0
|
|
273
|
+
for (const chunk of chunks) {
|
|
274
|
+
length += chunk.length
|
|
275
|
+
}
|
|
276
|
+
const out = new Uint8Array(length)
|
|
277
|
+
let offset = 0
|
|
278
|
+
for (const chunk of chunks) {
|
|
279
|
+
out.set(chunk, offset)
|
|
280
|
+
offset += chunk.length
|
|
281
|
+
}
|
|
282
|
+
return out
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function nodeCompressionRuntime(): compressionRuntime | null {
|
|
286
|
+
const processObj = (globalThis as any).process
|
|
287
|
+
if (processObj && typeof processObj.getBuiltinModule === 'function') {
|
|
288
|
+
const mod = processObj.getBuiltinModule('zlib')
|
|
289
|
+
if (mod && typeof mod.gzipSync === 'function') {
|
|
290
|
+
return {
|
|
291
|
+
gzipSync: (data, opts) => new Uint8Array(mod.gzipSync(data, opts)),
|
|
292
|
+
gunzipSync: (data) => new Uint8Array(mod.gunzipSync(data)),
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return null
|
|
297
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"strict": true,
|
|
4
|
+
"symbols": {
|
|
5
|
+
"BestCompression": {
|
|
6
|
+
"status": "real"
|
|
7
|
+
},
|
|
8
|
+
"BestSpeed": {
|
|
9
|
+
"status": "real"
|
|
10
|
+
},
|
|
11
|
+
"DefaultCompression": {
|
|
12
|
+
"status": "real"
|
|
13
|
+
},
|
|
14
|
+
"ErrChecksum": {
|
|
15
|
+
"status": "real"
|
|
16
|
+
},
|
|
17
|
+
"ErrHeader": {
|
|
18
|
+
"status": "real"
|
|
19
|
+
},
|
|
20
|
+
"Header": {
|
|
21
|
+
"status": "real"
|
|
22
|
+
},
|
|
23
|
+
"HuffmanOnly": {
|
|
24
|
+
"status": "real"
|
|
25
|
+
},
|
|
26
|
+
"NewReader": {
|
|
27
|
+
"status": "real"
|
|
28
|
+
},
|
|
29
|
+
"NewWriter": {
|
|
30
|
+
"status": "real"
|
|
31
|
+
},
|
|
32
|
+
"NewWriterLevel": {
|
|
33
|
+
"status": "real"
|
|
34
|
+
},
|
|
35
|
+
"NoCompression": {
|
|
36
|
+
"status": "real"
|
|
37
|
+
},
|
|
38
|
+
"Reader": {
|
|
39
|
+
"status": "real"
|
|
40
|
+
},
|
|
41
|
+
"Writer": {
|
|
42
|
+
"status": "real"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
4
|
+
import * as time from '@goscript/time/index.js'
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
Bool,
|
|
8
|
+
DefaultParameterConverter,
|
|
9
|
+
ErrBadConn,
|
|
10
|
+
ErrSkip,
|
|
11
|
+
Int32,
|
|
12
|
+
IsScanValue,
|
|
13
|
+
IsValue,
|
|
14
|
+
RowsAffected_LastInsertId,
|
|
15
|
+
RowsAffected_RowsAffected,
|
|
16
|
+
String,
|
|
17
|
+
} from './index.js'
|
|
18
|
+
|
|
19
|
+
function expectGoErrorThrow(fn: () => unknown, message: string): void {
|
|
20
|
+
try {
|
|
21
|
+
fn()
|
|
22
|
+
} catch (err) {
|
|
23
|
+
expect((err as $.GoError)?.Error()).toBe(message)
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
throw new Error('expected Go error throw')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe('database/sql/driver override', () => {
|
|
30
|
+
it('recognizes reflect-free Value-compatible inputs', () => {
|
|
31
|
+
expect(IsValue(null)).toBe(true)
|
|
32
|
+
expect(IsValue(new Uint8Array([1, 2]))).toBe(true)
|
|
33
|
+
expect(IsValue('query')).toBe(true)
|
|
34
|
+
expect(IsValue(true)).toBe(true)
|
|
35
|
+
expect(IsValue($.int(7, 64))).toBe(true)
|
|
36
|
+
expect(IsValue($.uint(8, 64))).toBe(true)
|
|
37
|
+
expect(IsValue(1.5)).toBe(true)
|
|
38
|
+
expect(IsValue(9n)).toBe(true)
|
|
39
|
+
expect(IsValue(new time.Time())).toBe(true)
|
|
40
|
+
expect(IsScanValue('scan')).toBe(true)
|
|
41
|
+
expect(IsValue({ unsupported: true })).toBe(false)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('converts supported Bool, String, and Int32 inputs', () => {
|
|
45
|
+
expect(Bool.ConvertValue(true)).toEqual([true, null])
|
|
46
|
+
expect(Bool.ConvertValue('true')).toEqual([true, null])
|
|
47
|
+
expect(Bool.ConvertValue(new Uint8Array([0x30]))).toEqual([false, null])
|
|
48
|
+
expect(String.ConvertValue('already')).toEqual(['already', null])
|
|
49
|
+
expect(Int32.ConvertValue(123)).toEqual([123, null])
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('guards reflect-dependent named and pointer converter arms', () => {
|
|
53
|
+
const namedBool = $.namedValueInterfaceValue<unknown>(
|
|
54
|
+
true,
|
|
55
|
+
'main.NamedBool',
|
|
56
|
+
{},
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
expectGoErrorThrow(
|
|
60
|
+
() => Bool.ConvertValue(namedBool),
|
|
61
|
+
'database/sql/driver: Bool.ConvertValue of named type is not supported in the GoScript browser build',
|
|
62
|
+
)
|
|
63
|
+
expectGoErrorThrow(
|
|
64
|
+
() => Int32.ConvertValue($.varRef(1)),
|
|
65
|
+
'database/sql/driver: Int32.ConvertValue of pointer is not supported in the GoScript browser build',
|
|
66
|
+
)
|
|
67
|
+
expectGoErrorThrow(
|
|
68
|
+
() => DefaultParameterConverter.ConvertValue($.varRef(1)),
|
|
69
|
+
'database/sql/driver: DefaultParameterConverter.ConvertValue of pointer is not supported in the GoScript browser build',
|
|
70
|
+
)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('round trips RowsAffected result methods', () => {
|
|
74
|
+
expect(RowsAffected_RowsAffected(42)).toEqual([42, null])
|
|
75
|
+
const [id, err] = RowsAffected_LastInsertId(42)
|
|
76
|
+
expect(id).toBe(0)
|
|
77
|
+
expect(err?.Error()).toBe('LastInsertId is not supported by this driver')
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('keeps sentinel error identity stable', () => {
|
|
81
|
+
const skip = ErrSkip
|
|
82
|
+
const bad = ErrBadConn
|
|
83
|
+
|
|
84
|
+
expect(ErrSkip).toBe(skip)
|
|
85
|
+
expect(ErrBadConn).toBe(bad)
|
|
86
|
+
expect(ErrSkip).not.toBe(ErrBadConn)
|
|
87
|
+
})
|
|
88
|
+
})
|